public CmsRecipientCollection (SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates) : base () { foreach (X509Certificate2 x509 in certificates) { CmsRecipient p7r = new CmsRecipient (recipientIdentifierType, x509); _list.Add (p7r); } }
public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) { switch (signerIdentifierType) { case SubjectIdentifierType.Unknown: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.IssuerAndSerialNumber: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.SubjectKeyIdentifier: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.NoSignature: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.None; break; default: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; } this.Certificate = certificate; this.DigestAlgorithm = new Oid("1.3.14.3.2.26"); this.m_signedAttributes = new CryptographicAttributeObjectCollection(); this.m_unsignedAttributes = new CryptographicAttributeObjectCollection(); this.m_certificates = new X509Certificate2Collection(); }
public EnvelopedCms (SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo) : this (contentInfo) { _idType = recipientIdentifierType; if (_idType == SubjectIdentifierType.SubjectKeyIdentifier) _version = 2; }
// constructor public CmsRecipient (X509Certificate2 certificate) { if (certificate == null) throw new ArgumentNullException ("certificate"); _recipient = SubjectIdentifierType.IssuerAndSerialNumber; _certificate = certificate; }
public CmsSigner (SubjectIdentifierType signerIdentifierType) : this () { if (signerIdentifierType == SubjectIdentifierType.Unknown) _signer = SubjectIdentifierType.IssuerAndSerialNumber; else _signer = signerIdentifierType; }
public CmsSigner (SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) { switch (signerIdentifierType) { case SubjectIdentifierType.Unknown: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.IssuerAndSerialNumber: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.SubjectKeyIdentifier: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.NoSignature: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.None; break; default: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; } this.Certificate = certificate; this.DigestAlgorithm = Oid.FromOidValue(CAPI.szOID_OIWSEC_sha1, OidGroup.HashAlgorithm); m_signedAttributes = new CryptographicAttributeObjectCollection(); m_unsignedAttributes = new CryptographicAttributeObjectCollection(); m_certificates = new X509Certificate2Collection(); }
private void Reset(SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate) { if (certificate == null) { throw new ArgumentNullException("certificate"); } switch (recipientIdentifierType) { case SubjectIdentifierType.Unknown: recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; break; case SubjectIdentifierType.IssuerAndSerialNumber: break; case SubjectIdentifierType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), recipientIdentifierType.ToString()); } this.m_recipientIdentifierType = recipientIdentifierType; this.m_certificate = certificate; }
internal SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { bool flag = true; byte* numPtr = (byte*)(void*)serialNumber.pbData; for (uint index = 0U; index < serialNumber.cbData; ++index) { if ((int)*numPtr++ != 0) { flag = false; break; } } if (flag) { byte[] numArray = new byte[(IntPtr)issuer.cbData]; Marshal.Copy(issuer.pbData, numArray, 0, numArray.Length); if (string.Compare("CN=Dummy Signer", new X500DistinguishedName(numArray).Name, StringComparison.OrdinalIgnoreCase) == 0) { this.Reset(SubjectIdentifierType.NoSignature, (object)null); return; } } if (flag) { this.m_type = SubjectIdentifierType.SubjectKeyIdentifier; this.m_value = (object)string.Empty; uint cbDecodedValue = 0U; SafeLocalAllocHandle decodedValue = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out decodedValue, out cbDecodedValue)) throw new CryptographicException(Marshal.GetLastWin32Error()); using (decodedValue) { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint index1 = 0U; index1 < certNameInfo.cRDN; ++index1) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)index1 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN))), typeof(CAPI.CERT_RDN)); for (uint index2 = 0U; index2 < certRdn.cRDNAttr; ++index2) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)index2 * (long)Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR))), typeof(CAPI.CERT_RDN_ATTR)); if (string.Compare("1.3.6.1.4.1.311.10.7.1", certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0 && (int)certRdnAttr.dwValueType == 2) { byte[] numArray = new byte[(IntPtr)certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, numArray, 0, numArray.Length); this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, (object)X509Utils.EncodeHexString(numArray)); return; } } } } throw new CryptographicException(-2146889715); } else { CAPI.CERT_ISSUER_SERIAL_NUMBER pIssuerAndSerial; pIssuerAndSerial.Issuer = issuer; pIssuerAndSerial.SerialNumber = serialNumber; this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, (object)PkcsUtils.DecodeIssuerSerial(pIssuerAndSerial)); } }
public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates) { this.m_recipients = new ArrayList(certificates.Count); for (int i = 0; i < certificates.Count; i++) { this.m_recipients.Add(new CmsRecipient(recipientIdentifierType, certificates[i])); } }
public CmsRecipientCollection (SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates) { // no null check, MS throws a NullReferenceException here foreach (X509Certificate2 x509 in certificates) { CmsRecipient p7r = new CmsRecipient (recipientIdentifierType, x509); _list.Add (p7r); } }
// constructors public CmsSigner () { _signer = SubjectIdentifierType.IssuerAndSerialNumber; _digest = new Oid ("1.3.14.3.2.26"); _options = X509IncludeOption.ExcludeRoot; _signed = new CryptographicAttributeObjectCollection (); _unsigned = new CryptographicAttributeObjectCollection (); _coll = new X509Certificate2Collection (); }
// only accessible from SignedPkcs7.SignerInfos internal SignerInfo (string hashName, X509Certificate2 certificate, SubjectIdentifierType type, object o, int version) { _digest = new Oid (CryptoConfig.MapNameToOID (hashName)); _certificate = certificate; _counter = new SignerInfoCollection (); _signed = new CryptographicAttributeObjectCollection (); _unsigned = new CryptographicAttributeObjectCollection (); _signer = new SubjectIdentifier (type, o); _version = version; }
public CmsRecipient (SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate) { if (certificate == null) throw new ArgumentNullException ("certificate"); if (recipientIdentifierType == SubjectIdentifierType.Unknown) _recipient = SubjectIdentifierType.IssuerAndSerialNumber; else _recipient = recipientIdentifierType; _certificate = certificate; }
public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates) { if (certificates == null) throw new NullReferenceException(); //Desktop compat: this is the wrong exception to throw but it is the compatible one. _recipients = new List<CmsRecipient>(certificates.Count); for (int index = 0; index < certificates.Count; index++) { _recipients.Add(new CmsRecipient(recipientIdentifierType, certificates[index])); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class. /// </summary> /// <remarks> /// The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to /// the Triple-DES encryption algorithm, which should be safe to assume for all modern /// S/MIME v3.x client implementations. /// </remarks> /// <param name="certificate">The recipient's certificate.</param> /// <param name="recipientIdentifierType">The recipient identifier type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="certificate"/> is <c>null</c>. /// </exception> public CmsRecipient (X509Certificate certificate, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) { if (certificate == null) throw new ArgumentNullException (nameof (certificate)); if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; else RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }; Certificate = certificate; }
public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm) { if (contentInfo == null) throw new ArgumentNullException("contentInfo"); if (contentInfo.Content == null) throw new ArgumentNullException("contentInfo.Content"); if (encryptionAlgorithm == null) throw new ArgumentNullException("encryptionAlgorithm"); this.m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; this.m_version = recipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 2 : 0; this.m_recipientIdentifierType = recipientIdentifierType; this.m_contentInfo = contentInfo; this.m_encryptionAlgorithm = encryptionAlgorithm; this.m_encryptionAlgorithm.Parameters = new byte[0]; this.m_certificates = new X509Certificate2Collection(); this.m_unprotectedAttributes = new CryptographicAttributeObjectCollection(); }
public SignedCms (SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached) { if (contentInfo == null) throw new ArgumentNullException("contentInfo"); if (contentInfo.Content == null) throw new ArgumentNullException("contentInfo.Content"); // Reset all states. if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier && signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber && signerIdentifierType != SubjectIdentifierType.NoSignature) { signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; } m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; m_signerIdentifierType = signerIdentifierType; m_version = 0; m_contentInfo = contentInfo; m_detached = detached; }
public SignedCms(SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.Pkcs.ContentInfo contentInfo, bool detached) { if (contentInfo == null) { throw new ArgumentNullException("contentInfo"); } if (contentInfo.Content == null) { throw new ArgumentNullException("contentInfo.Content"); } if (((signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier) && (signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber)) && (signerIdentifierType != SubjectIdentifierType.NoSignature)) { signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; } this.m_safeCryptMsgHandle = System.Security.Cryptography.SafeCryptMsgHandle.InvalidHandle; this.m_signerIdentifierType = signerIdentifierType; this.m_version = 0; this.m_contentInfo = contentInfo; this.m_detached = detached; }
public CmsRecipient(SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate) { if (certificate == null) throw new ArgumentNullException(nameof(certificate)); switch (recipientIdentifierType) { case SubjectIdentifierType.Unknown: recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; break; case SubjectIdentifierType.IssuerAndSerialNumber: break; case SubjectIdentifierType.SubjectKeyIdentifier: break; default: throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, recipientIdentifierType)); } RecipientIdentifierType = recipientIdentifierType; Certificate = certificate; }
public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached) { if (contentInfo == null) { throw new ArgumentNullException(nameof(contentInfo)); } if (contentInfo.Content == null) { throw new ArgumentNullException("contentInfo.Content"); } // signerIdentifierType is ignored. // In .NET Framework it is used for the signer type of a prompt-for-certificate signer. // In .NET Core we don't support prompting. // // .NET Framework turned any unknown value into IssuerAndSerialNumber, so no exceptions // are required, either. ContentInfo = contentInfo; Detached = detached; Version = 0; }
private static void CustomBuild_CertMatch( CertLoader loader, DateTimeOffset referenceTime, SigningCertificateOption v1Option, SigningCertificateOption v2Option, HashAlgorithmName v2AlgorithmName = default, X509IncludeOption includeOption = default, SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber) { byte[] tokenBytes = BuildCustomToken( loader, referenceTime, v1Option, v2Option, v2AlgorithmName, includeOption, identifierType); Rfc3161TimestampToken token; Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead)); Assert.Equal(tokenBytes.Length, bytesRead); Assert.NotNull(token); Assert.Equal(referenceTime, token.TokenInfo.Timestamp); using (X509Certificate2 cert = Certificates.ValidLookingTsaCert.GetCertificate()) { Assert.True( token.VerifySignatureForHash( token.TokenInfo.GetMessageHash().Span, token.TokenInfo.HashAlgorithmId, out X509Certificate2 signer, new X509Certificate2Collection(cert))); Assert.Equal(cert, signer); } }
internal SubjectIdentifier(SubjectIdentifierType type, object value) { Debug.Assert(value != null); #if DEBUG switch (type) { case SubjectIdentifierType.IssuerAndSerialNumber: Debug.Assert(value is X509IssuerSerial); break; case SubjectIdentifierType.SubjectKeyIdentifier: Debug.Assert(value is string); break; default: Debug.Fail($"Illegal type passed to SubjectIdentifier: {type}"); break; } #endif //DEBUG Type = type; Value = value; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class. /// </summary> /// <remarks> /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified stream.</para> /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to /// the Triple-DES encryption algorithm, which should be safe to assume for all modern /// S/MIME v3.x client implementations.</para> /// </remarks> /// <param name="stream">The stream containing the recipient's certificate.</param> /// <param name="recipientIdentifierType">The recipient identifier type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public CmsRecipient(Stream stream, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) { RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; } else { RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; } var parser = new X509CertificateParser(); EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }; RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; Certificate = parser.ReadCertificate(stream); }
internal SubjectIdentifier(SubjectIdentifierType type, object value) { Debug.Assert(value != null); #if DEBUG switch (type) { case SubjectIdentifierType.IssuerAndSerialNumber: Debug.Assert(value is X509IssuerSerial); break; case SubjectIdentifierType.SubjectKeyIdentifier: Debug.Assert(value is string); break; default: Debug.Fail($"Illegal type passed to SubjectIdentifier: {type}"); break; } #endif //DEBUG Type = type; Value = value; }
public static SubjectIdentifierOrKey ToSubjectIdentifierOrKey(this CERT_ID certId) { // // SubjectIdentifierOrKey is just a SubjectIdentifier with an (irrelevant here) "key" option thumbtacked onto it so // the easiest way is to subcontract the job to SubjectIdentifier. // SubjectIdentifier subjectIdentifier = certId.ToSubjectIdentifier(); SubjectIdentifierType subjectIdentifierType = subjectIdentifier.Type; switch (subjectIdentifierType) { case SubjectIdentifierType.IssuerAndSerialNumber: return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, subjectIdentifier.Value !)); case SubjectIdentifierType.SubjectKeyIdentifier: return(new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, subjectIdentifier.Value !)); default: Debug.Fail("Only the framework can construct SubjectIdentifier's so if we got a bad value here, that's our fault."); throw new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, subjectIdentifierType)); } }
internal void Reset(SubjectIdentifierType type, object value) { switch (type) { case SubjectIdentifierType.Unknown: case SubjectIdentifierType.NoSignature: this.m_type = type; this.m_value = value; break; case SubjectIdentifierType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } else { goto case 0; } case SubjectIdentifierType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } else { goto case 0; } default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), ((object)type).ToString()); } }
public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) { switch (signerIdentifierType) { case SubjectIdentifierType.Unknown: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.IssuerAndSerialNumber: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.SubjectKeyIdentifier: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; case SubjectIdentifierType.NoSignature: this.SignerIdentifierType = signerIdentifierType; this.IncludeOption = X509IncludeOption.None; break; default: this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; this.IncludeOption = X509IncludeOption.ExcludeRoot; break; } this.Certificate = certificate; string oidValue = LocalAppContextSwitches.CmsUseInsecureHashAlgorithms ? CAPI.szOID_OIWSEC_sha1 : Sha256Oid; this.DigestAlgorithm = Oid.FromOidValue(oidValue, OidGroup.HashAlgorithm); m_signedAttributes = new CryptographicAttributeObjectCollection(); m_unsignedAttributes = new CryptographicAttributeObjectCollection(); m_certificates = new X509Certificate2Collection(); }
/// <summary> /// Note: Due to its use of X509Certificate2Collection.Find(), this returns a cloned certificate. So the caller should dispose it. /// </summary> public static X509Certificate2 TryFindMatchingCertificate(this X509Certificate2Collection certs, SubjectIdentifier recipientIdentifier) { SubjectIdentifierType recipientIdentifierType = recipientIdentifier.Type; switch (recipientIdentifierType) { case SubjectIdentifierType.IssuerAndSerialNumber: { X509IssuerSerial issuerSerial = (X509IssuerSerial)(recipientIdentifier.Value); using (ClonedCertificates matches1 = certs.FindCertificates(X509FindType.FindBySerialNumber, issuerSerial.SerialNumber)) { using (ClonedCertificates matches2 = matches1.FindCertificates(X509FindType.FindByIssuerDistinguishedName, issuerSerial.IssuerName)) { // Desktop compat: We do not complain about multiple matches. Just take the first one and ignore the rest. return(matches2.Any ? matches2.ClaimResult() : null); } } } case SubjectIdentifierType.SubjectKeyIdentifier: { string ski = (string)(recipientIdentifier.Value); using (ClonedCertificates matches = certs.FindCertificates(X509FindType.FindBySubjectKeyIdentifier, ski)) { // Desktop compat: We do not complain about multiple matches. Just take the first one and ignore the rest. return(matches.Any ? matches.ClaimResult() : null); } } default: // RecipientInfo's can only be created by this package so if this an invalid type, it's the package's fault. Debug.Fail($"Invalid recipientIdentifier type: {recipientIdentifierType}"); throw new CryptographicException(); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class. /// </summary> /// <remarks> /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified file.</para> /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to /// the Triple-DES encryption algorithm, which should be safe to assume for all modern /// S/MIME v3.x client implementations.</para> /// </remarks> /// <param name="fileName">The file containing the recipient's certificate.</param> /// <param name="recipientIdentifierType">The recipient identifier type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fileName"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fileName"/> is a zero-length string, contains only white space, or /// contains one or more invalid characters as defined by /// <see cref="System.IO.Path.InvalidPathChars"/>. /// </exception> /// <exception cref="System.IO.DirectoryNotFoundException"> /// <paramref name="fileName"/> is an invalid file path. /// </exception> /// <exception cref="System.IO.FileNotFoundException"> /// The specified file path could not be found. /// </exception> /// <exception cref="System.UnauthorizedAccessException"> /// The user does not have access to read the specified file. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public CmsRecipient(string fileName, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) { if (fileName == null) { throw new ArgumentNullException(nameof(fileName)); } var parser = new X509CertificateParser(); if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) { RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; } else { RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; } EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }; RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; using (var stream = File.OpenRead(fileName)) Certificate = parser.ReadCertificate(stream); }
private static KeyTransRecipientInfo EncodeKeyTransl(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber) { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate()) { CmsRecipient cmsRecipient = new CmsRecipient(type, cert); ecms.Encrypt(cmsRecipient); } byte[] encodedMessage = ecms.Encode(); EnvelopedCms ecms2 = new EnvelopedCms(); ecms2.Decode(encodedMessage); RecipientInfoCollection recipients = ecms2.RecipientInfos; Assert.Equal(1, recipients.Count); RecipientInfo recipientInfo = recipients[0]; Assert.IsType <KeyTransRecipientInfo>(recipientInfo); return((KeyTransRecipientInfo)recipientInfo); }
private static void CheckSignedEncrypted(byte[] docBytes, SubjectIdentifierType expectedType) { SignedCms signedCms = new SignedCms(); signedCms.Decode(docBytes); Assert.Equal(Oids.Pkcs7Enveloped, signedCms.ContentInfo.ContentType.Value); SignerInfoCollection signers = signedCms.SignerInfos; Assert.Equal(1, signers.Count); Assert.Equal(expectedType, signers[0].SignerIdentifier.Type); // Assert.NotThrows signedCms.CheckSignature(true); EnvelopedCms envelopedCms = new EnvelopedCms(); envelopedCms.Decode(signedCms.ContentInfo.Content); using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey()) { envelopedCms.Decrypt(new X509Certificate2Collection(cert)); } Assert.Equal("42", envelopedCms.ContentInfo.Content.ByteArrayToHex()); }
public void Decode(byte[] encodedMessage) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.signedData) { throw new Exception(""); } PKCS7.SignedData sd = new PKCS7.SignedData(ci.Content); SubjectIdentifierType type = SubjectIdentifierType.Unknown; object o = null; X509Certificate2 x509 = null; if (sd.SignerInfo.Certificate != null) { x509 = new X509Certificate2(sd.SignerInfo.Certificate.RawData); } else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) { byte[] serial = sd.SignerInfo.SerialNumber; Array.Reverse(serial); // ??? type = SubjectIdentifierType.IssuerAndSerialNumber; X509IssuerSerial xis = new X509IssuerSerial(); xis.IssuerName = sd.SignerInfo.IssuerName; xis.SerialNumber = ToString(serial, true); o = xis; // TODO: move to a FindCertificate (issuer, serial, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (x.IssuerName == sd.SignerInfo.IssuerName) { if (ToString(x.SerialNumber, true) == xis.SerialNumber) { x509 = new X509Certificate2(x.RawData); break; } } } } else if (sd.SignerInfo.SubjectKeyIdentifier != null) { string ski = ToString(sd.SignerInfo.SubjectKeyIdentifier, false); type = SubjectIdentifierType.SubjectKeyIdentifier; o = (object)ski; // TODO: move to a FindCertificate (ski, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (ToString(GetKeyIdentifier(x), false) == ski) { x509 = new X509Certificate2(x.RawData); break; } } } SignerInfo si = new SignerInfo(sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version); // si.AuthenticatedAttributes // si.UnauthenticatedAttributes _info.Add(si); ASN1 content = sd.ContentInfo.Content; Oid oid = new Oid(sd.ContentInfo.ContentType); if (!_detached || _content == null) { if (content[0] == null) { throw new ArgumentException("ContentInfo has no content. Detached signature ?"); } _content = new ContentInfo(oid, content[0].Value); } foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { _certs.Add(new X509Certificate2(x.RawData)); } _version = sd.Version; }
private static void CustomBuild_CertMismatch( CertLoader loader, DateTimeOffset referenceTime, SigningCertificateOption v1Option, SigningCertificateOption v2Option, HashAlgorithmName v2AlgorithmName = default, X509IncludeOption includeOption = default, SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber) { byte[] tokenBytes = BuildCustomToken( loader, referenceTime, v1Option, v2Option, v2AlgorithmName, includeOption, identifierType); Rfc3161TimestampToken token; bool willParse = includeOption == X509IncludeOption.None; if (willParse && identifierType == SubjectIdentifierType.IssuerAndSerialNumber) { // Because IASN matches against the ESSCertId(V2) directly it will reject the token. switch (v1Option) { case SigningCertificateOption.ValidHashWithInvalidName: case SigningCertificateOption.ValidHashWithInvalidSerial: case SigningCertificateOption.InvalidHashWithInvalidName: case SigningCertificateOption.InvalidHashWithInvalidSerial: willParse = false; break; } switch (v2Option) { case SigningCertificateOption.ValidHashWithInvalidName: case SigningCertificateOption.ValidHashWithInvalidSerial: case SigningCertificateOption.InvalidHashWithInvalidName: case SigningCertificateOption.InvalidHashWithInvalidSerial: willParse = false; break; } } if (willParse) { Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead)); Assert.NotNull(token); Assert.Equal(tokenBytes.Length, bytesRead); using (X509Certificate2 cert = loader.GetCertificate()) { Assert.False( token.VerifySignatureForHash( token.TokenInfo.GetMessageHash().Span, token.TokenInfo.HashAlgorithmId, out X509Certificate2 signer, new X509Certificate2Collection(cert))); Assert.Null(signer); } } else { Assert.False(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead)); Assert.Null(token); Assert.Equal(0, bytesRead); } }
public CmsSigner (SubjectIdentifierType signerIdentifierType) : this (signerIdentifierType, null) {}
// // Internal methods. // internal void Reset (SubjectIdentifierType type, Object value) { switch (type) { case SubjectIdentifierType.NoSignature: case SubjectIdentifierType.Unknown: break; case SubjectIdentifierType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString()); } m_type = type; m_value = value; }
public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bool detached, string digestOid) { ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); SignedCms cms = new SignedCms(contentInfo, detached); using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; signer.DigestAlgorithm = new Oid(digestOid, digestOid); cms.ComputeSignature(signer); } Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; Assert.Equal(expectedVersion, cms.Version); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); Assert.NotNull(firstSigner.Certificate); Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); #if netcoreapp byte[] signature = firstSigner.GetSignature(); Assert.NotEmpty(signature); // ECDSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); // ECDSA Oids are all under 1.2.840.10045.4. Assert.StartsWith("1.2.840.10045.4.", firstSigner.SignatureAlgorithm.Value); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms = new SignedCms(); cms.Decode(encoded); Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); Assert.Equal(expectedVersion, cms.Version); Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); #if netcoreapp byte[] sig2 = cms.SignerInfos[0].GetSignature(); Assert.Equal(signature, sig2); #endif if (detached) { Assert.Throws <CryptographicException>(() => cms.CheckSignature(true)); cms = new SignedCms(contentInfo, detached); cms.Decode(encoded); } cms.CheckSignature(true); }
public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo content, bool detached) : this(content, detached) { _type = signerIdentifierType; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class. /// </summary> /// <remarks> /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified file.</para> /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to /// the Triple-DES encryption algorithm, which should be safe to assume for all modern /// S/MIME v3.x client implementations.</para> /// </remarks> /// <param name="fileName">The file containing the recipient's certificate.</param> /// <param name="recipientIdentifierType">The recipient identifier type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="fileName"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// <paramref name="fileName"/> is a zero-length string, contains only white space, or /// contains one or more invalid characters as defined by /// <see cref="System.IO.Path.InvalidPathChars"/>. /// </exception> /// <exception cref="System.IO.DirectoryNotFoundException"> /// <paramref name="fileName"/> is an invalid file path. /// </exception> /// <exception cref="System.IO.FileNotFoundException"> /// The specified file path could not be found. /// </exception> /// <exception cref="System.UnauthorizedAccessException"> /// The user does not have access to read the specified file. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public CmsRecipient (string fileName, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) { if (fileName == null) throw new ArgumentNullException (nameof (fileName)); var parser = new X509CertificateParser (); if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; else RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }; RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; using (var stream = File.OpenRead (fileName)) Certificate = parser.ReadCertificate (stream); }
public CmsSigner (SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) : this (signerIdentifierType) { _certificate = certificate; }
public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo) : this(signerIdentifierType, contentInfo, false) { }
private static KeyTransRecipientInfo FixedValueKeyTrans1(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber) { byte[] encodedMessage; switch (type) { case SubjectIdentifierType.IssuerAndSerialNumber: encodedMessage = s_KeyTransEncodedMessage; break; case SubjectIdentifierType.SubjectKeyIdentifier: encodedMessage = s_KeyTransEncodedMessage_Ski; break; default: throw new Exception("Bad SubjectIdentifierType."); } EnvelopedCms ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); RecipientInfoCollection recipients = ecms.RecipientInfos; Assert.Equal(1, recipients.Count); RecipientInfo recipientInfo = recipients[0]; Assert.True(recipientInfo is KeyTransRecipientInfo); return (KeyTransRecipientInfo)recipientInfo; }
private static KeyTransRecipientInfo EncodeKeyTransl(SubjectIdentifierType type = SubjectIdentifierType.IssuerAndSerialNumber) { ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo); using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate()) { CmsRecipient cmsRecipient = new CmsRecipient(type, cert); ecms.Encrypt(cmsRecipient); } byte[] encodedMessage = ecms.Encode(); EnvelopedCms ecms2 = new EnvelopedCms(); ecms2.Decode(encodedMessage); RecipientInfoCollection recipients = ecms2.RecipientInfos; Assert.Equal(1, recipients.Count); RecipientInfo recipientInfo = recipients[0]; Assert.True(recipientInfo is KeyTransRecipientInfo); return (KeyTransRecipientInfo)recipientInfo; }
public SignedCms(SubjectIdentifierType signerIdentifierType) : this() { _type = signerIdentifierType; }
public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) : this(signerIdentifierType, certificate, null) { }
public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo content) : this(content, false) { _type = signerIdentifierType; }
/// <summary> /// Initialize a new instance of the <see cref="CmsSigner"/> class. /// </summary> /// <remarks> /// <para>The initial value of the <see cref="DigestAlgorithm"/> will be set to /// <see cref="DigestAlgorithm.Sha256"/> and both the /// <see cref="SignedAttributes"/> and <see cref="UnsignedAttributes"/> properties /// will be initialized to empty tables.</para> /// </remarks> /// <param name="chain">The chain of certificates starting with the signer's certificate back to the root.</param> /// <param name="key">The signer's private key.</param> /// <param name="signerIdentifierType">The scheme used for identifying the signer certificate.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="chain"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="key"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para><paramref name="chain"/> did not contain any certificates.</para> /// <para>-or-</para> /// <para>The certificate cannot be used for signing.</para> /// <para>-or-</para> /// <para><paramref name="key"/> is not a private key.</para> /// </exception> public CmsSigner(IEnumerable <X509Certificate> chain, AsymmetricKeyParameter key, SubjectIdentifierType signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) : this() { if (chain == null) { throw new ArgumentNullException(nameof(chain)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } CertificateChain = new X509CertificateChain(chain); if (CertificateChain.Count == 0) { throw new ArgumentException("The certificate chain was empty.", nameof(chain)); } CheckCertificateCanBeUsedForSigning(CertificateChain[0]); if (!key.IsPrivate) { throw new ArgumentException("The key must be a private key.", nameof(key)); } if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier) { SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; } else { SignerIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; } Certificate = CertificateChain[0]; PrivateKey = key; }
public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool detached) { ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); SignedCms cms = new SignedCms(contentInfo, detached); using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; // Best compatibility for DSA is SHA-1 (FIPS 186-2) signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); cms.ComputeSignature(signer); } Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; Assert.Equal(expectedVersion, cms.Version); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); Assert.NotNull(firstSigner.Certificate); Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); #if netcoreapp byte[] signature = firstSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms = new SignedCms(); cms.Decode(encoded); Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); Assert.Equal(expectedVersion, cms.Version); Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); #if netcoreapp byte[] sig2 = cms.SignerInfos[0].GetSignature(); Assert.Equal(signature, sig2); #endif if (detached) { Assert.Throws <CryptographicException>(() => cms.CheckSignature(true)); cms = new SignedCms(contentInfo, detached); cms.Decode(encoded); } cms.CheckSignature(true); }
internal unsafe SubjectIdentifier (CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte * pb = (byte *) serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte) 0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). Note that some certificates may contain // an all-zero serial number but not be encoded with an szOID_KEYID_RDN. In order to allow use of signatures created // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just // decoding the incoming issuer and serial number. m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) { using (pbCertNameInfo) { checked { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO) Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN) Marshal.PtrToStructure(new IntPtr((long) certNameInfo.rgRDN + (long) (i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } } } } CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); }
public static void EnsureDataIsolation_NewDocument(bool detached) { byte[] contentBytes = { 9, 8, 7, 6, 5 }; ContentInfo contentInfo = new ContentInfo(contentBytes); SignedCms cms = new SignedCms(contentInfo, detached); SubjectIdentifierType firstType = SubjectIdentifierType.IssuerAndSerialNumber; SubjectIdentifierType secondType = SubjectIdentifierType.SubjectKeyIdentifier; using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(firstType, signerCert); signer.SignedAttributes.Add(new Pkcs9SigningTime()); cms.ComputeSignature(signer); } // CheckSignature doesn't read the public mutable data contentInfo.Content[0] ^= 0xFF; contentInfo.ContentType.Value = Oids.Pkcs7Hashed; cms.CheckSignature(true); using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(secondType, signerCert); signer.SignedAttributes.Add(new Pkcs9SigningTime()); // A second ComputeSignature uses the content value from the first one. cms.ComputeSignature(signer); } // They should have the same content digests. AsnEncodedData firstDigest = cms.SignerInfos[0].SignedAttributes .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0]; AsnEncodedData secondDigest = cms.SignerInfos[1].SignedAttributes .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0]; Assert.Equal(firstDigest.RawData.ByteArrayToHex(), secondDigest.RawData.ByteArrayToHex()); byte[] encoded = cms.Encode(); if (detached) { cms.Decode(encoded); // Because Decode leaves ContentInfo alone, and Decode resets the // "known" content, this will fail due to the tampered content. Assert.Throws <CryptographicException>(() => cms.CheckSignature(true)); // So put it back. cms.ContentInfo.Content[0] ^= 0xFF; } cms.Decode(encoded); if (detached) { // And break it again. cms.ContentInfo.Content[0] ^= 0xFF; } // Destroy the content that just got decoded. encoded.AsSpan().Fill(0x55); cms.CheckSignature(true); }
internal SubjectIdentifier(SubjectIdentifierType type, object value) { _type = type; _value = value; }
internal SubjectIdentifier (SubjectIdentifierType type, Object value) { Reset(type, value); }
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()); }
internal unsafe SubjectIdentifier(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB issuer, System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB serialNumber) { System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER cert_issuer_serial_number; bool flag = true; byte *pbData = (byte *)serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { pbData++; if (pbData[0] != 0) { flag = false; break; } } if (flag) { byte[] destination = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, destination, 0, destination.Length); X500DistinguishedName name = new X500DistinguishedName(destination); if (string.Compare("CN=Dummy Signer", name.Name, StringComparison.OrdinalIgnoreCase) == 0) { this.Reset(SubjectIdentifierType.NoSignature, null); return; } } if (flag) { this.m_type = SubjectIdentifierType.SubjectKeyIdentifier; this.m_value = string.Empty; uint cbDecodedValue = 0; System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.DecodeObject(new IntPtr(7L), issuer.pbData, issuer.cbData, out invalidHandle, out cbDecodedValue)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } using (invalidHandle) { System.Security.Cryptography.CAPI.CERT_NAME_INFO cert_name_info = (System.Security.Cryptography.CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(invalidHandle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_NAME_INFO)); for (uint j = 0; j < cert_name_info.cRDN; j++) { System.Security.Cryptography.CAPI.CERT_RDN cert_rdn = (System.Security.Cryptography.CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr(((long)cert_name_info.rgRDN) + (j * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN)); for (uint k = 0; k < cert_rdn.cRDNAttr; k++) { System.Security.Cryptography.CAPI.CERT_RDN_ATTR cert_rdn_attr = (System.Security.Cryptography.CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr(((long)cert_rdn.rgRDNAttr) + (k * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR)))), typeof(System.Security.Cryptography.CAPI.CERT_RDN_ATTR)); if ((string.Compare("1.3.6.1.4.1.311.10.7.1", cert_rdn_attr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) && (cert_rdn_attr.dwValueType == 2)) { byte[] buffer2 = new byte[cert_rdn_attr.Value.cbData]; Marshal.Copy(cert_rdn_attr.Value.pbData, buffer2, 0, buffer2.Length); this.Reset(SubjectIdentifierType.SubjectKeyIdentifier, System.Security.Cryptography.X509Certificates.X509Utils.EncodeHexString(buffer2)); return; } } } } throw new CryptographicException(-2146889715); } cert_issuer_serial_number.Issuer = issuer; cert_issuer_serial_number.SerialNumber = serialNumber; X509IssuerSerial serial = PkcsUtils.DecodeIssuerSerial(cert_issuer_serial_number); this.Reset(SubjectIdentifierType.IssuerAndSerialNumber, serial); }
public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { }
public CmsSigner(SubjectIdentifierType signerIdentifierType) : this(signerIdentifierType, null) { }
internal unsafe SubjectIdentifier(CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte *pb = (byte *)serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte)0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). Note that some certificates may contain // an all-zero serial number but not be encoded with an szOID_KEYID_RDN. In order to allow use of signatures created // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just // decoding the incoming issuer and serial number. m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) { using (pbCertNameInfo) { checked { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO)Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN)Marshal.PtrToStructure(new IntPtr((long)certNameInfo.rgRDN + (long)(i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } } } } CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); }
private void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type, ContentInfo expectedContentInfo = null) { // Deep-copy the contentInfo since the real ContentInfo doesn't do this. This defends against a bad implementation changing // our "expectedContentInfo" to match what it produces. expectedContentInfo = expectedContentInfo ?? new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone())); string certSubjectName; byte[] encodedMessage; byte[] originalCopy = (byte[])(contentInfo.Content.Clone()); using (X509Certificate2 certificate = certLoader.GetCertificate()) { certSubjectName = certificate.Subject; AlgorithmIdentifier alg = new AlgorithmIdentifier(new Oid(algorithmOidValue)); EnvelopedCms ecms = new EnvelopedCms(contentInfo, alg); CmsRecipient cmsRecipient = new CmsRecipient(type, certificate); ecms.Encrypt(cmsRecipient); Assert.Equal(originalCopy.ByteArrayToHex(), ecms.ContentInfo.Content.ByteArrayToHex()); encodedMessage = ecms.Encode(); } // We don't pass "certificate" down because it's expected that the certificate used for encrypting doesn't have a private key (part of the purpose of this test is // to ensure that you don't need the recipient's private key to encrypt.) The decrypt phase will have to locate the matching cert with the private key. VerifySimpleDecrypt(encodedMessage, certLoader, expectedContentInfo); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.CmsRecipient"/> class. /// </summary> /// <remarks> /// <para>Creates a new <see cref="CmsRecipient"/>, loading the certificate from the specified stream.</para> /// <para>The initial value of the <see cref="EncryptionAlgorithms"/> property will be set to /// the Triple-DES encryption algorithm, which should be safe to assume for all modern /// S/MIME v3.x client implementations.</para> /// </remarks> /// <param name="stream">The stream containing the recipient's certificate.</param> /// <param name="recipientIdentifierType">The recipient identifier type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public CmsRecipient (Stream stream, SubjectIdentifierType recipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber) { if (stream == null) throw new ArgumentNullException (nameof (stream)); if (recipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber) RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; else RecipientIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier; var parser = new X509CertificateParser (); EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }; RecipientIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber; Certificate = parser.ReadCertificate (stream); }
public static void AddCounterSigner_ECDSA(SubjectIdentifierType identifierType, string digestOid) { SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); Assert.Single(cms.Certificates); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; signer.DigestAlgorithm = new Oid(digestOid, digestOid); firstSigner.ComputeCounterSignature(signer); } Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); SignerInfo firstSigner2 = cms.SignerInfos[0]; Assert.Single(firstSigner2.CounterSignerInfos); Assert.Single(firstSigner2.UnsignedAttributes); Assert.Single(cms.SignerInfos); Assert.Equal(2, cms.Certificates.Count); SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; int expectedVersion = identifierType == SubjectIdentifierType.IssuerAndSerialNumber ? 1 : 3; Assert.Equal(expectedVersion, counterSigner.Version); // On NetFx there will be two attributes, because Windows emits the // content-type attribute even for counter-signers. int expectedCount = 1; #if netfx expectedCount = 2; #endif Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); #if netcoreapp byte[] signature = counterSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); // ECDSA Oids are all under 1.2.840.10045.4. Assert.StartsWith("1.2.840.10045.4.", counterSigner.SignatureAlgorithm.Value); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms.Decode(encoded); cms.CheckSignature(true); }
internal SubjectIdentifier(SubjectIdentifierType type, object value) { this.Reset(type, value); }