private bool VerifyS3Message(byte[] s3Message) { // Convert S3 message from byte array into the compatible structure object S3MessageObj = new SigmaDataStructs.SigmaS3Message(); GeneralUtils.ByteArrayToStructure(s3Message, ref S3MessageObj); SigmaDataStructs.SigmaS3Message S3Message = (SigmaDataStructs.SigmaS3Message)S3MessageObj; // Locate the data index in the message int dataInd = Marshal.SizeOf(typeof(SigmaDataStructs.SigmaS3Message)) - 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.VerifyHmac(dataForHmac, dataForHmac.Length, S3Message.S3Icv, SigmaDataStructs.SIGMA_MAC_LEN, SMK, SigmaDataStructs.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[SigmaDataStructs.EPID_SIG_LEN]; if (!SigmaUtils.DoesBKExist(S3Message, ref GaGbSig)) { return(false); } // groupCert contains the SIGMA 1.0 certificate for the specific EPID group ID byte[] groupCert = SigmaUtils.GetSpecificEpidCertificate_SIGMA_1_0(epidGroupID); // epidParamsCert contains the mathematic parameters byte[] epidParamsData = File.ReadAllBytes(EPIDDataStructs.PRODUCTION_SIGNED_BIN_PARAMS_CERT_FILE); // Verify message. If a revocation list is used - the dll function will also check that the platform was not revoked. status = CryptoDataGenWrapper.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); }
/** * Gets the provisioning data (including the mathematic parameters and certificate) according to the platform EPID group ID */ private static byte[] CreateProvisioningData(uint GroupID) { // Provisioning data buffer EPIDDataStructs.ProvisioningDataSigma1_1 provisioningData = new EPIDDataStructs.ProvisioningDataSigma1_1(); // Build provisioning data // Header provisioningData.Header.ApiVersion = (uint)SigmaDataStructs.SIGMA_API_VERSION_1_1; provisioningData.Header.CommandId = (uint)EPIDDataStructs.CommandId.CMD_SEND_SAFEID_PUBKEY; provisioningData.Header.Status = 0; // CryptoContext - contains the mathematic parameters provisioningData.CryptoContext = File.ReadAllBytes(EPIDDataStructs.DEBUG_SIGNED_BIN_PARAMS_CERT_FILE); // SafeIdCert - contains the SIGMA1_0 certificate for the specific EPID group ID provisioningData.SafeIdCert = SigmaUtils.GetSpecificEpidCertificate_SIGMA_1_0(GroupID); // tempCert contains the SIGMA 1.1 certificate for the specific EPID group ID byte[] tempCert = SigmaUtils.GetSpecificEpidCertificate_SIGMA_1_1(GroupID); // Calculate the needed padding length int paddingLen = (4 - (DataStructs.VLR_HEADER_LEN + tempCert.Length) % 4) % 4; // Pad original cert so it will be word aligned byte[] paddedCert = new byte[tempCert.Length + paddingLen]; tempCert.CopyTo(paddedCert, 0); tempCert = paddedCert; // Set EPID group certificate provisioningData.X509GroupCert = new EPIDDataStructs.X509GroupCertificate(); provisioningData.X509GroupCert.vlrHeader.ID = (byte)DataStructs.VlrIdType.X509_GROUP_CERTIFICATE_VLR_ID; provisioningData.X509GroupCert.vlrHeader.VLRLength = (short)(DataStructs.VLR_HEADER_LEN + tempCert.Length); provisioningData.X509GroupCert.vlrHeader.PaddedBytes = (byte)paddingLen; provisioningData.Header.BufferLength = (uint)(Marshal.SizeOf(typeof(EPIDDataStructs.ProvisioningDataSigma1_1)) - Marshal.SizeOf(typeof(EPIDDataStructs.SessionMgrCmdHdr)) + tempCert.Length); //cert has a different length byte[] provisioningDataArray = GeneralUtils.StructureToByteArray(provisioningData); // The provisioning data contains the whole data: dataArray and the SIGMA 1.1 certificate for the specific EPID group ID byte[] provisioningDataAndCert = new byte[provisioningDataArray.Length + tempCert.Length]; Array.Copy(provisioningDataArray, provisioningDataAndCert, provisioningDataArray.Length); Array.Copy(tempCert, 0, provisioningDataAndCert, provisioningDataArray.Length, tempCert.Length); return(provisioningDataAndCert); }
public override void HandleClientCommunication(object client) { try { TcpClient tcpClient = (TcpClient)client; Socket socket = tcpClient.Client; isClientConnected = socket.Connected; while (isClientConnected) { // Receive adapted message (message prepared for verification) int dataSize = socket.ReceiveMessageAsInt(); byte[] adaptedMessage = socket.ReceiveMessage(dataSize); // Receive signature dataSize = socket.ReceiveMessageAsInt(); byte[] signature = socket.ReceiveMessage(dataSize); // Receive EPID group ID int groupID = socket.ReceiveMessageAsInt(); // groupCert contains the SIGMA 1.1 certificate for the specific EPID group ID byte[] groupCert = SigmaUtils.GetSpecificEpidCertificate_SIGMA_1_0((uint)groupID); // epidParamsCert contains the mathematic parameters byte[] epidParamsCert = File.ReadAllBytes(EPIDDataStructs.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 = GeneralUtils.StructureToByteArray(EPIDDataStructs.GetTaskInfo()); byte[] infoNonceMessage = new byte[taskInfoArray.Length + adaptedMessage.Length]; //TaskInfo || Nonce || Message // Concatenate the info to infoNonceMessage taskInfoArray.CopyTo(infoNonceMessage, 0); // Concatenate the adapted message(including the nonce) to infoNonceMessage adaptedMessage.CopyTo(infoNonceMessage, taskInfoArray.Length); // 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 - a list of the platforms that were revoked based on the platform’s private key // SignatureRevList - a list of the platforms that were revoked based on the signature generated by the platform // GroupRevList - a list of the EPID groups that were revoked based on the group public key // as parameters. CdgResult retStatus; CdgStatus status = CryptoDataGenWrapper.MessageVerifyPch(groupCert, groupCert.Length, epidParamsCert, infoNonceMessage, infoNonceMessage.Length, null, 0, signature, signature.Length, out retStatus, null, null, null); int res = VERIFYNG_SUCCESS; if (status != CdgStatus.CdgStsOk) { res = ERROR; } else if (retStatus != CdgResult.CdgValid) { res = VERIFYNG_FAILED; } // Send the signature verification result to the client socket.SendInt(res); } Console.WriteLine("EPID Signing Sample Client disconnected.\n"); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
private bool GetS2Message(out byte[] S2MessageArray) { S2MessageArray = new byte[0]; byte[] cert = SigmaDataStructs.Sigma11_3PSignedCert; // Verifier's certificate byte[] key = SigmaDataStructs.Sigma11_Signed3PKey; // Verifier's private key // Get the OCSP (Online Certificate Status Protocol) response according to the request we've got from the prover byte[] OCSPResp = SigmaUtils.GetOCSPResponseFromRealResponder(cert, OCSPReq.OcspNonce); // If there is a problem with the OCSP server connection if (OCSPResp == null) { return(false); } try { // Create S2 structure SigmaDataStructs.SigmaS2Message S2Message = GenerateS2Structure(); // Build the OCSP response OCSPResp = SigmaUtils.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 = SigmaUtils.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 = GeneralUtils.StructureToByteArray(S2Message.OcspReq); // Preparing the HMAC // Constructing HMAC data - Gb || Basename || OCSP Req || Verifier Cert || Sig-RL List || OCSPResp byte[] dataForHmac = new byte[SigmaDataStructs.SIGMA_PUBLIC_KEY_LEN + SigmaDataStructs.BASE_NAME_LENGTH + DataStructs.INT_SIZE + SigmaDataStructs.OCSP_NONCE_LENGTH + VerifierCertAndOCSPResp.Length]; S2Message.Gb.CopyTo(dataForHmac, 0); S2Message.Basename.CopyTo(dataForHmac, SigmaDataStructs.SIGMA_PUBLIC_KEY_LEN); ocspReqArray.CopyTo(dataForHmac, SigmaDataStructs.SIGMA_PUBLIC_KEY_LEN + SigmaDataStructs.BASE_NAME_LENGTH); VerifierCertAndOCSPResp.CopyTo(dataForHmac, SigmaDataStructs.SIGMA_PUBLIC_KEY_LEN + SigmaDataStructs.BASE_NAME_LENGTH + DataStructs.INT_SIZE + SigmaDataStructs.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[SigmaDataStructs.SIGMA_MAC_LEN]; status = CryptoDataGenWrapper.CreateHmac(dataForHmac, dataForHmac.Length, SMK, SigmaDataStructs.SIGMA_SMK_LENGTH, S2Message.S2Icv, SigmaDataStructs.SIGMA_HMAC_LENGTH); if (status != CdgStatus.CdgStsOk) { return(false); } // Create Signed [Ga || Gb] using verifier ECDSA private key S2Message.SigGaGb = new byte[SigmaDataStructs.ECDSA_SIGNATURE_LEN]; status = CryptoDataGenWrapper.MessageSign(key, key.Length, GaGb, SigmaDataStructs.SIGMA_KEY_LENGTH * 2, S2Message.SigGaGb, SigmaDataStructs.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]; GeneralUtils.StructureToByteArray(S2Message).CopyTo(S2MessageArray, 0); VerifierCertAndOCSPResp.CopyTo(S2MessageArray, s2MessageLen); return(true); } catch (Exception) { return(false); } }