public static SignedCertificateTimestamp ParseSCTFromBinary(InputStream inputStream) { SignedCertificateTimestamp sctBuilder = new SignedCertificateTimestamp(); int version = (int)ReadNumber(inputStream, 1); if (version != (int)Version.V1) { throw new SerializationException(string.Format("Unknown version: %d", version)); } sctBuilder.Version = (Version)version; _ = ReadUint16(inputStream); byte[] keyId = ReadFixedLength(inputStream, CTConstants.KeyIdLength); var id_ = new LogID(); id_.KeyId = ByteString.CopyFrom(keyId); sctBuilder.Id = id_; var timestamp = (ulong)ReadNumber(inputStream, CTConstants.TimestampLength); sctBuilder.Timestamp = timestamp; byte[] extensions = ReadVariableLength(inputStream, CTConstants.MaxExtensionsLength); sctBuilder.Extensions = ByteString.CopyFrom(extensions); sctBuilder.Signature = ParseDigitallySignedFromBinary(inputStream); return(sctBuilder); }
private static void serializeCommonSCTFields(SignedCertificateTimestamp sct, MemoryStream bos) { if (sct.Version.Equals(Version.V1)) { Debug.WriteLine("Can only serialize SCT v1 for now."); } Serializer.WriteUint(bos, (long)Convert.ToDouble(sct.Version), CTConstants.VersionLength); // ct::V1 Serializer.WriteUint(bos, 0, 1); // ct::CERTIFICATE_TIMESTAMP Serializer.WriteUint(bos, (long)sct.Timestamp, CTConstants.TimestampLength); // Timestamp }
/** * Verifies the CT Log's signature over the SCT and certificate. Works for the following cases: * * <ul> * <li>Ordinary X509 certificate sent to the log. * <li>PreCertificate signed by an ordinary CA certificate. * <li>PreCertificate signed by a PreCertificate Signing Cert. In this case the PreCertificate * signing certificate must be 2nd on the chain, the CA cert itself 3rd. * </ul> * * @param sct SignedCertificateTimestamp received from the log. * @param chain The certificates chain as sent to the log. * @return true if the log's signature over this SCT can be verified, false otherwise. */ public bool VerifySignature(SignedCertificateTimestamp sct, List <X509Certificate> chain) { if (sct != null && !logInfo.IsSameLogId(sct.Id.KeyId.ToByteArray())) { throw new CertificateTransparencyException( "Log ID of SCT does not match this log's ID ."); } return(true); }
/** * Verifies the CT Log's signature over the SCT and leaf certificate. * * @param sct SignedCertificateTimestamp received from the log. * @param leafCert leaf certificate sent to the log. * @return true if the log's signature over this SCT can be verified, false otherwise. */ bool verifySignature(SignedCertificateTimestamp sct, Certificate leafCert) { if (!logInfo.Equals(sct.Id)) { throw new CertificateTransparencyException( string.Format( "Log ID of SCT () does not match this log's ID.")); } byte[] toVerify = serializeSignedSCTData(leafCert, sct); return(verifySCTSignatureOverBytes(sct, toVerify)); }
static byte[] serializeSignedSCTData(Certificate certificate, SignedCertificateTimestamp sct) { MemoryStream bos = new MemoryStream(); serializeCommonSCTFields(sct, bos); Serializer.WriteUint(bos, (long)LogEntryType.X509Entry, CTConstants.LogEntryTypeLength); try { Serializer.WriteVariableLength(bos, certificate.GetEncoded(), CTConstants.MaxCertificateLength); } catch (CertificateEncodingException e) { throw new CertificateTransparencyException("Error encoding certificate", e); } Serializer.WriteVariableLength(bos, sct.Extensions.ToByteArray(), CTConstants.MaxExtensionsLength); return(bos.ToArray()); }
private bool verifySCTSignatureOverBytes(SignedCertificateTimestamp sct, byte[] toVerify) { string sigAlg; if (logInfo.SignatureAlgorithm.Equals("EC")) { sigAlg = "SHA256withECDSA"; } else if (logInfo.SignatureAlgorithm.Equals("RSA")) { sigAlg = "SHA256withRSA"; } else { throw new CertificateTransparencyException("Unsupported signature algorithm %s"); } try { Signature signature = Signature.GetInstance(sigAlg); //X509EncodedKeySpec spec = new X509EncodedKeySpec(logInfo.Key); //KeyFactory keyFactory = KeyFactory.GetInstance("RSA"); //IPrivateKey pk = (IPrivateKey)keyFactory.GeneratePublic(spec); signature.InitSign((IPrivateKey)logInfo.Key); signature.Update(toVerify); return(signature.Verify(sct.Signature.Signature.ToByteArray())); } catch (SignatureException e) { throw new CertificateTransparencyException( "Signature object not properly initialized or signature from SCT is improperly encoded.", e); } catch (InvalidKeyException e) { throw new CertificateTransparencyException("Log's public key cannot be used", e); } catch (NoSuchAlgorithmException e) { throw new UnsupportedCryptoPrimitiveException(sigAlg + " not supported by this JVM", e); } }
static byte[] serializeSignedSCTDataForPreCertificate(byte[] preCertBytes, byte[] issuerKeyHash, SignedCertificateTimestamp sct) { MemoryStream bos = new MemoryStream(); serializeCommonSCTFields(sct, bos); Serializer.WriteUint(bos, (long)LogEntryType.PrecertEntry, CTConstants.LogEntryTypeLength); Serializer.WriteVariableLength(bos, issuerKeyHash, issuerKeyHash.Length); Serializer.WriteVariableLength(bos, preCertBytes, CTConstants.MaxCertificateLength); Serializer.WriteVariableLength(bos, sct.Extensions.ToByteArray(), CTConstants.MaxExtensionsLength); return(bos.ToArray()); }