private void VerifySimpleDecrypt(byte[] encodedMessage, CertLoader certLoader, ContentInfo expectedContent) { EnvelopedCms ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 cert = certLoader.TryGetCertificateWithPrivateKey()) { if (cert == null) { return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. } #if netcoreapp // API not present on netfx if (_useExplicitPrivateKey) { using (X509Certificate2 pubCert = certLoader.GetCertificate()) { RecipientInfo recipient = ecms.RecipientInfos.Cast <RecipientInfo>().Where((r) => r.RecipientIdentifier.MatchesCertificate(cert)).Single(); ecms.Decrypt(recipient, cert.PrivateKey); } } else #endif { X509Certificate2Collection extraStore = new X509Certificate2Collection(cert); ecms.Decrypt(extraStore); } ContentInfo contentInfo = ecms.ContentInfo; Assert.Equal(expectedContent.ContentType.Value, contentInfo.ContentType.Value); Assert.Equal(expectedContent.Content.ByteArrayToHex(), contentInfo.Content.ByteArrayToHex()); } }
private static void Assert_Certificate_Roundtrip(CertLoader certificateLoader) { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); using (X509Certificate2 cert = certificateLoader.GetCertificate()) { CmsRecipient recipient = new CmsRecipient(cert); ecms.Encrypt(recipient); } byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 privateCert = certificateLoader.TryGetCertificateWithPrivateKey()) { if (privateCert == null) { return; // CertLoader can't load the private certificate. } ecms.Decrypt(new X509Certificate2Collection(privateCert)); } Assert.Equal(contentInfo.ContentType.Value, ecms.ContentInfo.ContentType.Value); Assert.Equal <byte>(contentInfo.Content, ecms.ContentInfo.Content); }
public static void DecryptMultipleRecipients() { // Force Decrypt() to try multiple recipients. Ensure that a failure to find a matching cert in one doesn't cause it to quit early. CertLoader[] certLoaders = new CertLoader[] { Certificates.RSAKeyTransfer1, Certificates.RSAKeyTransfer2, Certificates.RSAKeyTransfer3, }; byte[] content = { 6, 3, 128, 33, 44 }; EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), new AlgorithmIdentifier(new Oid(Oids.Aes256))); CmsRecipientCollection recipients = new CmsRecipientCollection(); foreach (CertLoader certLoader in certLoaders) { recipients.Add(new CmsRecipient(certLoader.GetCertificate())); } ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); // How do we know that Decrypt() tries receipients in the order they appear in ecms.RecipientInfos? Because we wrote the implementation. // Not that some future implementation can't ever change it but it's the best guess we have. RecipientInfo me = ecms.RecipientInfos[2]; CertLoader matchingCertLoader = null; for (int index = 0; index < recipients.Count; index++) { if (recipients[index].Certificate.Issuer == ((X509IssuerSerial)(me.RecipientIdentifier.Value)).IssuerName) { matchingCertLoader = certLoaders[index]; break; } } Assert.NotNull(matchingCertLoader); using (X509Certificate2 cert = matchingCertLoader.TryGetCertificateWithPrivateKey()) { if (cert == null) { return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. } X509Certificate2Collection extraStore = new X509Certificate2Collection(); extraStore.Add(cert); ecms.Decrypt(extraStore); } ContentInfo contentInfo = ecms.ContentInfo; Assert.Equal <byte>(content, contentInfo.Content); }
public void EncryptToNegativeSerialNumber() { CertLoader negativeSerial = Certificates.NegativeSerialNumber; const string expectedSerial = "FD319CB1514B06AF49E00522277E43C8"; byte[] content = { 1, 2, 3 }; ContentInfo contentInfo = new ContentInfo(content); EnvelopedCms cms = new EnvelopedCms(contentInfo); using (X509Certificate2 cert = negativeSerial.GetCertificate()) { Assert.Equal(expectedSerial, cert.SerialNumber); CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, cert); cms.Encrypt(recipient); } EnvelopedCms cms2 = new EnvelopedCms(); cms2.Decode(cms.Encode()); RecipientInfoCollection recipients = cms2.RecipientInfos; Assert.Equal(1, recipients.Count); RecipientInfo recipientInfo = recipients[0]; Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, recipientInfo.RecipientIdentifier.Type); X509IssuerSerial issuerSerial = (X509IssuerSerial)recipientInfo.RecipientIdentifier.Value; Assert.Equal(expectedSerial, issuerSerial.SerialNumber); using (X509Certificate2 cert = negativeSerial.TryGetCertificateWithPrivateKey()) { Assert.Equal(expectedSerial, cert.SerialNumber); cms2.Decrypt(new X509Certificate2Collection(cert)); } Assert.Equal(content, cms2.ContentInfo.Content); }
private static void VerifySimpleDecrypt(byte[] encodedMessage, CertLoader certLoader, ContentInfo expectedContent) { EnvelopedCms ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 cert = certLoader.TryGetCertificateWithPrivateKey()) { if (cert == null) { return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. } X509Certificate2Collection extraStore = new X509Certificate2Collection(cert); ecms.Decrypt(extraStore); ContentInfo contentInfo = ecms.ContentInfo; Assert.Equal(expectedContent.ContentType.Value, contentInfo.ContentType.Value); Assert.Equal <byte>(expectedContent.Content, contentInfo.Content); } }
private static byte[] BuildCustomToken( CertLoader cert, DateTimeOffset timestamp, SigningCertificateOption v1Option, SigningCertificateOption v2Option, HashAlgorithmName v2DigestAlg = default, X509IncludeOption includeOption = X509IncludeOption.ExcludeRoot, SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber) { long accuracyMicroSeconds = (long)(TimeSpan.FromMinutes(1).TotalMilliseconds * 1000); byte[] serialNumber = BitConverter.GetBytes(DateTimeOffset.UtcNow.Ticks); Array.Reverse(serialNumber); Rfc3161TimestampTokenInfo info = new Rfc3161TimestampTokenInfo( new Oid("0.0", "0.0"), new Oid(Oids.Sha384), new byte[384 / 8], serialNumber, timestamp, accuracyMicroSeconds, isOrdering: true); ContentInfo contentInfo = new ContentInfo(new Oid(Oids.TstInfo, Oids.TstInfo), info.Encode()); SignedCms cms = new SignedCms(contentInfo); using (X509Certificate2 tsaCert = cert.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, tsaCert) { IncludeOption = includeOption }; if (v1Option != SigningCertificateOption.Omit) { ExpandOption(v1Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial); // simple SigningCertificate byte[] signingCertificateV1Bytes = "301A3018301604140000000000000000000000000000000000000000".HexToByteArray(); if (validHash) { byte[] hash = SHA1.HashData(tsaCert.RawData); Buffer.BlockCopy( hash, 0, signingCertificateV1Bytes, signingCertificateV1Bytes.Length - hash.Length, hash.Length); } if (!skipIssuerSerial) { byte[] footer = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial); signingCertificateV1Bytes[1] += (byte)footer.Length; signingCertificateV1Bytes[3] += (byte)footer.Length; signingCertificateV1Bytes[5] += (byte)footer.Length; Assert.InRange(signingCertificateV1Bytes[1], 0, 127); signingCertificateV1Bytes = signingCertificateV1Bytes.Concat(footer).ToArray(); } signer.SignedAttributes.Add( new AsnEncodedData("1.2.840.113549.1.9.16.2.12", signingCertificateV1Bytes)); } if (v2Option != SigningCertificateOption.Omit) { byte[] attrBytes; byte[] algBytes = Array.Empty <byte>(); byte[] hashBytes; byte[] issuerNameBytes = Array.Empty <byte>(); if (v2DigestAlg != default) { switch (v2DigestAlg.Name) { case "MD5": algBytes = "300C06082A864886F70D02050500".HexToByteArray(); break; case "SHA1": algBytes = "300906052B0E03021A0500".HexToByteArray(); break; case "SHA256": // Invalid under DER, because it's the default. algBytes = "300D06096086480165030402010500".HexToByteArray(); break; case "SHA384": algBytes = "300D06096086480165030402020500".HexToByteArray(); break; case "SHA512": algBytes = "300D06096086480165030402030500".HexToByteArray(); break; default: throw new NotSupportedException(v2DigestAlg.Name); } } else { v2DigestAlg = HashAlgorithmName.SHA256; } hashBytes = tsaCert.GetCertHash(v2DigestAlg); ExpandOption(v2Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial); if (!validHash) { hashBytes[0] ^= 0xFF; } if (!skipIssuerSerial) { issuerNameBytes = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial); } // hashBytes hasn't been wrapped in an OCTET STRING yet, so add 2 more. int payloadSize = algBytes.Length + hashBytes.Length + issuerNameBytes.Length + 2; Assert.InRange(payloadSize, 0, 123); attrBytes = new byte[payloadSize + 6]; int index = 0; // SEQUENCE (SigningCertificateV2) attrBytes[index++] = 0x30; attrBytes[index++] = (byte)(payloadSize + 4); // SEQUENCE OF => certs attrBytes[index++] = 0x30; attrBytes[index++] = (byte)(payloadSize + 2); // SEQUENCE (ESSCertIdV2) attrBytes[index++] = 0x30; attrBytes[index++] = (byte)payloadSize; Buffer.BlockCopy(algBytes, 0, attrBytes, index, algBytes.Length); index += algBytes.Length; // OCTET STRING (Hash) attrBytes[index++] = 0x04; attrBytes[index++] = (byte)hashBytes.Length; Buffer.BlockCopy(hashBytes, 0, attrBytes, index, hashBytes.Length); index += hashBytes.Length; Buffer.BlockCopy(issuerNameBytes, 0, attrBytes, index, issuerNameBytes.Length); signer.SignedAttributes.Add( new AsnEncodedData("1.2.840.113549.1.9.16.2.47", attrBytes)); } cms.ComputeSignature(signer); } return(cms.Encode()); }