private SigmaDataStructs.SigmaS2Message GenerateS2Structure() { SigmaDataStructs.SigmaS2Message S2Message = new SigmaDataStructs.SigmaS2Message(); // Fill the S2 fields S2Message.Basename = new byte[SigmaDataStructs.BASE_NAME_LENGTH]; // The base name, chosen by the verifier, to be used in name based signatures. here you can use baseName, in case you want to do it. S2Message.Gb = Gb; // The Verifier's ephemeral DH public key S2Message.OcspReq = OCSPReq; // An (optional) OCSP Request from the prover return(S2Message); }
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); } }