//Verify S3 message public bool VerifyS3Message(byte[] s3Message) { //Convert S3 message from byte array into the compatible structure object S3MessageObj = new DataStructs.SIGMA_S3_MESSAGE(); Utils.ByteArrayToStructure(s3Message, ref S3MessageObj); DataStructs.SIGMA_S3_MESSAGE S3Message = (DataStructs.SIGMA_S3_MESSAGE)S3MessageObj; //Locate the data index in the message int dataInd = Marshal.SizeOf(typeof(DataStructs.SIGMA_S3_MESSAGE)) - 1 + 32; //Copy S3 message data from the received message into the S3 strucure data field S3Message.data = new byte[s3Message.Length - dataInd]; Array.Copy(s3Message, dataInd, S3Message.data, 0, S3Message.data.Length); //Prepare data for HMAC byte[] dataForHmac = new byte[s3Message.Length - S3Message.S3Icv.Length]; Array.Copy(s3Message, S3Message.S3Icv.Length, dataForHmac, 0, dataForHmac.Length); //Verify HMAC CdgResult retStat = CdgResult.CdgValid; CdgStatus status; status = CryptoDataGenWrapper_1_1.VerifyHmac(dataForHmac, dataForHmac.Length, S3Message.S3Icv, DataStructs.SIGMA_MAC_LEN, SMK, DataStructs.SIGMA_SMK_LENGTH, ref retStat); if (status != CdgStatus.CdgStsOk || retStat != CdgResult.CdgValid) { return(false); } //Check whether BK exists in the signed message, as a part of the S3 message validation byte[] GaGbSig = new byte[DataStructs.EPID_SIG_LEN]; if (!DoesBKExist(S3Message, ref GaGbSig)) { return(false); } //groupCert contains the SIGMA1_0 certificate for the specific EPID group ID byte[] groupCert = Utils.GetSpecificEpidCertificate_SIGMA_1_0((uint)groupID); //epidParamsCert contains the mathematic parameters byte[] epidParamsData = File.ReadAllBytes(DataStructs.PRODUCTION_SIGNED_BIN_PARAMS_CERT_FILE); //Verify message. In case that a revocation list is used - the dll function will also check that the platform was not revoked. status = CryptoDataGenWrapper_1_1.MessageVerifyPch(groupCert, groupCert.Length, epidParamsData, GaGb, GaGb.Length, null, 0, GaGbSig, GaGbSig.Length, out retStat, null); if (status != CdgStatus.CdgStsOk || retStat != CdgResult.CdgValid) { return(false); } return(true); }
//Process S1 message public CdgStatus ProcessS1Message(byte[] s1Msg) { //Convert S1 message from byte array into the compatible structure object s1Message = new DataStructs.SIGMA_S1_MESSAGE(); Utils.ByteArrayToStructure(s1Msg, ref s1Message); //Extract S1 message DataStructs.SIGMA_S1_MESSAGE message = (DataStructs.SIGMA_S1_MESSAGE)s1Message; Ga = message.Ga; //Prover's ephemeral DH public key OCSPReq = message.OcspReq; //An (optional) OCSP Request from the prover groupID = message.Gid; //platform EPID group ID //Derive SK(Session Confidentiality Key: 128 bit), MK(Session Integrity Key: 128bit) and SMK(Session Message Key) CdgStatus status = CryptoDataGenWrapper_1_1.DeriveSigmaKeys(Ga, Ga.Length, Gb, Gb.Length, Sk, Sk.Length, Mk, Mk.Length, SMK, SMK.Length); return(status); }
private bool validateSignature(byte[] adaptedMessage, byte[] signature) { //groupCert contains the SIGMA1_0 certificate for the specific EPID group ID byte[] groupCert = Utils.GetSpecificEpidCertificate_SIGMA_1_0((uint)groupID); //epidParamsCert contains the mathematic parameters byte[] epidParamsCert = File.ReadAllBytes(DataStructs.DEBUG_SIGNED_BIN_PARAMS_CERT_FILE); // taskInfoArray is a data structure defined in the DAL implementation. It is prepended to the message by DAL prior to signing, // and so has to be prepened by us prior to verification byte[] taskInfoArray = Utils.StructureToByteArray(DataStructs.GetTaskInfo()); byte[] infoNonceMessage = new byte[taskInfoArray.Length + adaptedMessage.Length]; //TaskInfo || Nonce || Message taskInfoArray.CopyTo(infoNonceMessage, 0); //concatenate the info to infoNonceMessage adaptedMessage.CopyTo(infoNonceMessage, taskInfoArray.Length); //concatenate the adapted message(including the nonce) to infoNonceMessage //Verify the signature //When we call the MessageVerifyPch function, we can send //baseName - the basename that will be signed as part of the signature //privateKeyRevList - list of the platforms that were revoked based on the platform’s private key //SignatureRevList - list of the platforms that were revoked based on the signature generated by the platform //GroupRevList - list of the EPID groups that were revoked based on the group public key //as parameters. CdgResult retStatus; CdgStatus status = CryptoDataGenWrapper_1_1.MessageVerifyPch(groupCert, groupCert.Length, epidParamsCert, infoNonceMessage, infoNonceMessage.Length, null, 0, signature, signature.Length, out retStatus, null, null, null); if (status != CdgStatus.CdgStsOk) { return(false); } else if (retStatus != CdgResult.CdgValid) { return(false); } else { return(true); } }
public void handleClientComm(object client) { try { TcpClient tcpClient = (TcpClient)client; Socket socket = tcpClient.Client; clientConnected = socket.Connected; while (clientConnected) { byte[] dataSize = new byte[4]; int received, size, total, dataLeft; //receive adapted message(message prepared for verification) received = socket.Receive(dataSize, 0, 4, 0); size = BitConverter.ToInt32(dataSize, 0); total = 0; dataLeft = size; byte[] adaptedMessage = new byte[size]; while (total < size) { received = socket.Receive(adaptedMessage, total, dataLeft, 0); if (received == 0) { break; } total += received; dataLeft -= received; } //receive signature received = socket.Receive(dataSize, 0, 4, 0); size = BitConverter.ToInt32(dataSize, 0); total = 0; dataLeft = size; byte[] signature = new byte[size]; while (total < size) { received = socket.Receive(signature, total, dataLeft, 0); if (received == 0) { break; } total += received; dataLeft -= received; } //receive EPID groupID byte[] groupIDByteArray = new byte[4]; socket.Receive(groupIDByteArray, 0, 4, 0); int groupID = Utils.ByteArrayToInt(groupIDByteArray); //groupCert contains the SIGMA1_0 certificate for the specific EPID group ID byte[] groupCert = Utils.GetSpecificEpidCertificate_SIGMA_1_0((uint)groupID); //epidParamsCert contains the mathematic parameters byte[] epidParamsCert = File.ReadAllBytes(DataStructs.DEBUG_SIGNED_BIN_PARAMS_CERT_FILE); // taskInfoArray is a data structure defined in the DAL implementation. It is prepended to the message by DAL prior to signing, // and so has to be prepended by us prior to verification byte[] taskInfoArray = Utils.StructureToByteArray(DataStructs.GetTaskInfo()); byte[] infoNonceMessage = new byte[taskInfoArray.Length + adaptedMessage.Length]; //TaskInfo || Nonce || Message taskInfoArray.CopyTo(infoNonceMessage, 0); //concatenate the info to infoNonceMessage adaptedMessage.CopyTo(infoNonceMessage, taskInfoArray.Length); //concatenate the adapted message(including the nonce) to infoNonceMessage //Verify the signature //When we call the MessageVerifyPch function, we can send //baseName - the basename that will be signed as part of the signature //privateKeyRevList - list of the platforms that were revoked based on the platform’s private key //SignatureRevList - list of the platforms that were revoked based on the signature generated by the platform //GroupRevList - list of the EPID groups that were revoked based on the group public key //as parameters. CdgResult retStatus; CdgStatus status = CryptoDataGenWrapper_1_1.MessageVerifyPch(groupCert, groupCert.Length, epidParamsCert, infoNonceMessage, infoNonceMessage.Length, null, 0, signature, signature.Length, out retStatus, null, null, null); int res; if (status != CdgStatus.CdgStsOk) { res = ERROR; } else if (retStatus != CdgResult.CdgValid) { res = VERIFYNG_FAILED; } else { res = VERIFYNG_SUCCESS; } byte[] result = new byte[4]; result = BitConverter.GetBytes(res); //Send the signature verification result to the client socket.Send(result); } Console.WriteLine("EPID Signing Sample Client disconnected.\n"); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
//Get S2 message public bool GetS2Message(out byte[] S2MessageArray) { S2MessageArray = new byte[0]; byte[] cert = DataStructs.Sigma11_3PSignedCert; //Verifier's certificate byte[] key = DataStructs.Sigma11_Signed3PKey; //Verifier's private key //Get the OCSP response according to the request we've got from the proover OCSPResp = GetOCSPResponseFromRealResponder(cert, OCSPReq.OcspNonce); //if there is a problem with the OCSP server connection if (OCSPResp == null) { return(false); } try { //Create S2 structure DataStructs.SIGMA_S2_MESSAGE S2Message = GenerateS2Structure(); //Build the OCSP response OCSPResp = BuildOCSPResp(cert, OCSPResp); //Composing - Data contains Verifier Cert, SIG_RL_HEADER followed by Revocation List , OCSP Response (If requested) VLRs in this order. SigRL is optional. List <byte> VerifierCertAndOCSPRespList = new List <byte>(); //Generate X509 verifier certificate byte[] x509VerifierCertArray = GenerateX509VerifierCert(cert); //Add the x509VerifierCert to S2 message VerifierCertAndOCSPRespList.AddRange(x509VerifierCertArray); //Here you can generate SIG-RL in case you want to use it, and add it to s2List //Add the OCSP response to S2 message VerifierCertAndOCSPRespList.AddRange(OCSPResp); //Convert VerifierCert and OCSPResp list to a byte array byte[] VerifierCertAndOCSPResp = VerifierCertAndOCSPRespList.ToArray(); //Convert OCSP request from structure to a byte array byte[] ocspReqArray = Utils.StructureToByteArray(S2Message.OcspReq); //Preparing the HMAC //Constructing HMAC data - Gb || Basename || OCSP Req || Verifier Cert || Sig-RL List || OCSPResp byte[] dataForHmac = new byte[DataStructs.SIGMA_PUBLIC_KEY_LEN + DataStructs.BASE_NAME_LENGTH + DataStructs.INT_SIZE + DataStructs.OCSP_NONCE_LENGTH + VerifierCertAndOCSPResp.Length]; S2Message.Gb.CopyTo(dataForHmac, 0); S2Message.Basename.CopyTo(dataForHmac, DataStructs.SIGMA_PUBLIC_KEY_LEN); ocspReqArray.CopyTo(dataForHmac, DataStructs.SIGMA_PUBLIC_KEY_LEN + DataStructs.BASE_NAME_LENGTH); VerifierCertAndOCSPResp.CopyTo(dataForHmac, DataStructs.SIGMA_PUBLIC_KEY_LEN + DataStructs.BASE_NAME_LENGTH + DataStructs.INT_SIZE + DataStructs.OCSP_NONCE_LENGTH); //Create HMAC - HMAC_SHA256 of [Gb || Basename || OCSP Req || Verifier Cert || Sig-RL List ], using SMK CdgStatus status; S2Message.S2Icv = new byte[DataStructs.SIGMA_MAC_LEN]; status = CryptoDataGenWrapper_1_1.CreateHmac(dataForHmac, dataForHmac.Length, SMK, DataStructs.SIGMA_SMK_LENGTH, S2Message.S2Icv, DataStructs.SIGMA_HMAC_LENGTH); if (status != CdgStatus.CdgStsOk) { return(false); } //Create Signed [Ga || Gb] using verifier ECDSA public key S2Message.SigGaGb = new byte[DataStructs.ECDSA_SIGNATURE_LEN]; status = CryptoDataGenWrapper_1_1.MessageSign(key, key.Length, GaGb, DataStructs.SIGMA_KEY_LENGTH * 2, S2Message.SigGaGb, DataStructs.ECDSA_SIGNATURE_LEN); if (status != CdgStatus.CdgStsOk) { return(false); } //Prepare final S2 message array contains S2 message structure + verifier cert + OCSP response int s2MessageLen = Marshal.SizeOf(S2Message); S2MessageArray = new byte[s2MessageLen + VerifierCertAndOCSPResp.Length]; Utils.StructureToByteArray(S2Message).CopyTo(S2MessageArray, 0); VerifierCertAndOCSPResp.CopyTo(S2MessageArray, s2MessageLen); return(true); } catch (Exception e) { return(false); } }