public static void Rc4AndCngWrappersDontMixTest() { // // Combination of RC4 over a CAPI certificate. // // This works as long as the PKCS implementation opens the cert using CAPI. If he creates a CNG wrapper handle (by passing CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG), // the test fails with a NOTSUPPORTED crypto exception inside Decrypt(). The same happens if the key is genuinely CNG. // byte[] content = { 6, 3, 128, 33, 44 }; AlgorithmIdentifier rc4 = new AlgorithmIdentifier(new Oid(Oids.Rc4)); EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), rc4); CmsRecipientCollection recipients = new CmsRecipientCollection(new CmsRecipient(Certificates.RSAKeyTransferCapi1.GetCertificate())); ecms.Encrypt(recipients); byte[] encodedMessage = ecms.Encode(); ecms = new EnvelopedCms(); ecms.Decode(encodedMessage); using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.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); }
//BUG [ExpectedException (typeof (ArgumentNullException))] public void ConstructorOidNull () { AlgorithmIdentifier ai = new AlgorithmIdentifier (null); Assert.IsNull (ai.Oid, "Oid"); Assert.AreEqual (0, ai.KeyLength, "KeyLength"); Assert.AreEqual (0, ai.Parameters.Length, "Parameters"); }
private void Reset(int version) { this.m_version = version; this.m_recipientIdentifier = null; this.m_encryptionAlgorithm = null; this.m_encryptedKey = new byte[0]; }
public sealed override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes)) { byte[] encodedContent; if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase)) { unsafe { byte[] content = contentInfo.Content; fixed (byte* pContent = content) { DATA_BLOB blob = new DATA_BLOB((IntPtr)pContent, (uint)(content.Length)); encodedContent = Interop.Crypt32.CryptEncodeObjectToByteArray(CryptDecodeObjectStructType.X509_OCTET_STRING, &blob); } } } else { encodedContent = contentInfo.Content; } if (encodedContent.Length > 0) { if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true)) throw Marshal.GetLastWin32Error().ToCryptographicException(); } byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM); return encodedMessage; } }
public void ConstructorOidKeyLength () { Oid o = new Oid (validOid); AlgorithmIdentifier ai = new AlgorithmIdentifier (o, 128); Assert.AreEqual (128, ai.KeyLength, "KeyLength"); Assert.AreEqual (validOid, ai.Oid.Value, "Oid"); Assert.AreEqual (0, ai.Parameters.Length, "Parameters"); }
/// <summary> /// Initializes a new instance of the OpaqueMail.SmtpClient class by using configuration file settings. /// </summary> public SmtpClient() : base() { SmimeAlgorithmIdentifier = new AlgorithmIdentifier(new Oid("2.16.840.1.101.3.4.1.42")); SmimeValidCertificates = null; RandomizeBoundaryNames(); }
// only accessible from EnvelopedCms.RecipientInfos internal KeyTransRecipientInfo (byte[] encryptedKey, AlgorithmIdentifier keyEncryptionAlgorithm, SubjectIdentifier recipientIdentifier, int version) : base (RecipientInfoType.KeyTransport) { _encryptedKey = encryptedKey; _keyEncryptionAlgorithm = keyEncryptionAlgorithm; _recipientIdentifier = recipientIdentifier; _version = version; }
public EnvelopedCms (ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm) : this (contentInfo) { if (encryptionAlgorithm == null) throw new ArgumentNullException ("encryptionAlgorithm"); _identifier = encryptionAlgorithm; }
public void ConstructorEmpty () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); Assert.AreEqual (0, ai.KeyLength, "KeyLength"); Assert.AreEqual (defaultName, ai.Oid.FriendlyName, "Oid.FriendlyName"); Assert.AreEqual (defaultOid, ai.Oid.Value, "Oid.Value"); Assert.AreEqual (0, ai.Parameters.Length, "Parameters"); }
internal PublicKeyInfo(AlgorithmIdentifier algorithm, byte[] keyValue) { Debug.Assert(algorithm != null); Debug.Assert(keyValue != null); Algorithm = algorithm; KeyValue = keyValue; }
internal PublicKeyInfo(System.Security.Cryptography.CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { this.m_algorithm = new AlgorithmIdentifier(keyInfo); this.m_keyValue = new byte[keyInfo.PublicKey.cbData]; if (this.m_keyValue.Length > 0) { Marshal.Copy(keyInfo.PublicKey.pbData, this.m_keyValue, 0, this.m_keyValue.Length); } }
public static void DecodeAlgorithmDes_RoundTrip() { AlgorithmIdentifier algorithm = new AlgorithmIdentifier(new Oid(Oids.Des)); ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 }); EnvelopedCms ecms = new EnvelopedCms(contentInfo, algorithm); using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate()) { CmsRecipient cmsRecipient = new CmsRecipient(cert); ecms.Encrypt(cmsRecipient); } byte[] encodedMessage = ecms.Encode(); VerifyAlgorithmDes(encodedMessage); }
private void Reset(uint originatorChoice, uint version, System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo, uint subIndex) { this.m_encryptedKeyInfo = encryptedKeyInfo; this.m_originatorChoice = originatorChoice; this.m_version = (int) version; this.m_originatorIdentifier = null; this.m_userKeyMaterial = new byte[0]; this.m_encryptionAlgorithm = null; this.m_recipientIdentifier = null; this.m_encryptedKey = new byte[0]; this.m_date = DateTime.MinValue; this.m_otherKeyAttribute = null; this.m_subIndex = subIndex; }
public EnvelopedCms(ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm) { if (contentInfo == null) throw new ArgumentNullException(nameof(contentInfo)); if (encryptionAlgorithm == null) throw new ArgumentNullException(nameof(encryptionAlgorithm)); Version = 0; // It makes little sense to ask for a version before you've decoded, but since the desktop returns 0 in that case, we will too. ContentInfo = contentInfo; ContentEncryptionAlgorithm = encryptionAlgorithm; Certificates = new X509Certificate2Collection(); UnprotectedAttributes = new CryptographicAttributeObjectCollection(); _decryptorPal = null; _lastCall = LastCall.Ctor; }
Stream Envelope(RealCmsRecipientCollection recipients, Stream content, EncryptionAlgorithm encryptionAlgorithm) { var contentInfo = new ContentInfo(ReadAllBytes(content)); RealAlgorithmIdentifier algorithm; switch (encryptionAlgorithm) { case EncryptionAlgorithm.Aes256: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes256Cbc)); break; case EncryptionAlgorithm.Aes192: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes192Cbc)); break; case EncryptionAlgorithm.Aes128: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes128Cbc)); break; case EncryptionAlgorithm.RC2128: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 128); break; case EncryptionAlgorithm.RC264: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 64); break; case EncryptionAlgorithm.RC240: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 40); break; default: algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.DesEde3Cbc)); break; } var envelopedData = new EnvelopedCms(contentInfo, algorithm); envelopedData.Encrypt(recipients); return(new MemoryStream(envelopedData.Encode(), false)); }
internal static DecryptorPalWindows Decode( byte[] encodedMessage, out int version, out ContentInfo contentInfo, out AlgorithmIdentifier contentEncryptionAlgorithm, out X509Certificate2Collection originatorCerts, out CryptographicAttributeObjectCollection unprotectedAttributes ) { SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToDecode(MsgEncodingType.All, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (hCryptMsg == null || hCryptMsg.IsInvalid) throw Marshal.GetLastWin32Error().ToCryptographicException(); if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedMessage, encodedMessage.Length, fFinal: true)) throw Marshal.GetLastWin32Error().ToCryptographicException(); CryptMsgType cryptMsgType = hCryptMsg.GetMessageType(); if (cryptMsgType != CryptMsgType.CMSG_ENVELOPED) throw ErrorCode.CRYPT_E_INVALID_MSG_TYPE.ToCryptographicException(); version = hCryptMsg.GetVersion(); contentInfo = hCryptMsg.GetContentInfo(); using (SafeHandle sh = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_ENVELOPE_ALGORITHM_PARAM)) { unsafe { CRYPT_ALGORITHM_IDENTIFIER* pCryptAlgorithmIdentifier = (CRYPT_ALGORITHM_IDENTIFIER*)(sh.DangerousGetHandle()); contentEncryptionAlgorithm = (*pCryptAlgorithmIdentifier).ToAlgorithmIdentifier(); } } originatorCerts = hCryptMsg.GetOriginatorCerts(); unprotectedAttributes = hCryptMsg.GetUnprotectedAttributes(); RecipientInfoCollection recipientInfos = CreateRecipientInfos(hCryptMsg); return new DecryptorPalWindows(hCryptMsg, recipientInfos); }
public static SafeCryptMsgHandle CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (HeapBlockRetainer hb = new HeapBlockRetainer()) { // Deep copy the CmsRecipients (and especially their underlying X509Certificate2 objects). This will prevent malicious callers from altering them or disposing them while we're performing // unsafe memory crawling inside them. recipients = recipients.DeepCopy(); // We must keep all the certificates inside recipients alive until the call to CryptMsgOpenToEncode() finishes. The CMSG_ENVELOPED_ENCODE_INFO* structure we passed to it // contains direct pointers to memory owned by the CERT_INFO memory block whose lifetime is that of the certificate. hb.KeepAlive(recipients); unsafe { CMSG_ENVELOPED_ENCODE_INFO* pEnvelopedEncodeInfo = CreateCmsEnvelopedEncodeInfo(recipients, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, hb); SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToEncode(MsgEncodingType.All, 0, CryptMsgType.CMSG_ENVELOPED, pEnvelopedEncodeInfo, innerContentType.Value, IntPtr.Zero); if (hCryptMsg == null || hCryptMsg.IsInvalid) throw Marshal.GetLastWin32Error().ToCryptographicException(); return hCryptMsg; } } }
public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, System.Security.Cryptography.Pkcs.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 = System.Security.Cryptography.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 void ConstructorSubjectIdentifierTypeUnknownContentInfoAlgorithmIdentifier () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ContentInfo ci = new ContentInfo (asnNull); EnvelopedCms ep = new EnvelopedCms (SubjectIdentifierType.Unknown, ci, ai); DefaultProperties (ep, 2, 0); }
// constructors // only used in KeyAgreeRecipientInfo.OriginatorIdentifierOrKey.Value // when SubjectIdentifierOrKeyType == PublicKeyInfo internal PublicKeyInfo (AlgorithmIdentifier algorithm, byte[] key) { _algorithm = algorithm; _key = key; }
public void Parameters () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ai.Parameters = new byte[2] { 0x05, 0x00 }; // ASN.1 NULL Assert.AreEqual ("05-00", BitConverter.ToString (ai.Parameters), "Parameters"); ai.Parameters = null; Assert.IsNull (ai.Parameters, "Parameters-Null"); }
public void Oid () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ai.Oid = new Oid (validOid); Assert.AreEqual (validOid, ai.Oid.Value, "Oid"); ai.Oid = null; Assert.IsNull (ai.Oid, "Oid-Null"); }
public void KeyLength () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ai.KeyLength = Int32.MaxValue; Assert.AreEqual (Int32.MaxValue, ai.KeyLength, "KeyLength-Max"); ai.KeyLength = 0; Assert.AreEqual (0, ai.KeyLength, "KeyLength-Zero"); ai.KeyLength = Int32.MinValue; Assert.AreEqual (Int32.MinValue, ai.KeyLength, "KeyLength-Min"); }
public static AlgorithmIdentifier ToAlgorithmIdentifier(this CRYPT_ALGORITHM_IDENTIFIER cryptAlgorithmIdentifer) { string oidValue = cryptAlgorithmIdentifer.pszObjId.ToStringAnsi(); AlgId algId = oidValue.ToAlgId(); int keyLength; switch (algId) { case AlgId.CALG_RC2: { if (cryptAlgorithmIdentifer.Parameters.cbData == 0) { keyLength = 0; } else { CRYPT_RC2_CBC_PARAMETERS rc2Parameters; unsafe { int cbSize = sizeof(CRYPT_RC2_CBC_PARAMETERS); if (!Interop.Crypt32.CryptDecodeObject(CryptDecodeObjectStructType.PKCS_RC2_CBC_PARAMETERS, cryptAlgorithmIdentifer.Parameters.pbData, (int)(cryptAlgorithmIdentifer.Parameters.cbData), &rc2Parameters, ref cbSize)) throw Marshal.GetLastWin32Error().ToCryptographicException(); } switch (rc2Parameters.dwVersion) { case CryptRc2Version.CRYPT_RC2_40BIT_VERSION: keyLength = KeyLengths.Rc2_40Bit; break; case CryptRc2Version.CRYPT_RC2_56BIT_VERSION: keyLength = KeyLengths.Rc2_56Bit; break; case CryptRc2Version.CRYPT_RC2_64BIT_VERSION: keyLength = KeyLengths.Rc2_64Bit; break; case CryptRc2Version.CRYPT_RC2_128BIT_VERSION: keyLength = KeyLengths.Rc2_128Bit; break; default: keyLength = 0; break; } } break; } case AlgId.CALG_RC4: { int saltLength = 0; if (cryptAlgorithmIdentifer.Parameters.cbData != 0) { using (SafeHandle sh = Interop.Crypt32.CryptDecodeObjectToMemory(CryptDecodeObjectStructType.X509_OCTET_STRING, cryptAlgorithmIdentifer.Parameters.pbData, (int)cryptAlgorithmIdentifer.Parameters.cbData)) { unsafe { DATA_BLOB* pDataBlob = (DATA_BLOB*)(sh.DangerousGetHandle()); saltLength = (int)(pDataBlob->cbData); } } } // For RC4, keyLength = 128 - (salt length * 8). keyLength = KeyLengths.Rc4Max_128Bit - saltLength * 8; break; } case AlgId.CALG_DES: // DES key length is fixed at 64 (or 56 without the parity bits). keyLength = KeyLengths.Des_64Bit; break; case AlgId.CALG_3DES: // 3DES key length is fixed at 192 (or 168 without the parity bits). keyLength = KeyLengths.TripleDes_192Bit; break; default: // We've exhausted all the algorithm types that the desktop used to set the KeyLength for. Key lengths are not a viable way of // identifying algorithms in the long run so we will not extend this list any further. keyLength = 0; break; } AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Oid.FromOidValue(oidValue, OidGroup.All), keyLength); return algorithmIdentifier; }
public static SubjectIdentifierOrKey ToSubjectIdentifierOrKey(this CERT_PUBLIC_KEY_INFO publicKeyInfo) { int keyLength = Interop.Crypt32.CertGetPublicKeyLength(MsgEncodingType.All, ref publicKeyInfo); string oidValue = publicKeyInfo.Algorithm.pszObjId.ToStringAnsi(); AlgorithmIdentifier algorithmId = new AlgorithmIdentifier(Oid.FromOidValue(oidValue, OidGroup.PublicKeyAlgorithm), keyLength); byte[] keyValue = publicKeyInfo.PublicKey.ToByteArray(); PublicKeyInfo pki = new PublicKeyInfo(algorithmId, keyValue); return new SubjectIdentifierOrKey(SubjectIdentifierOrKeyType.PublicKeyInfo, pki); }
private static void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type) { // 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. ContentInfo expectedContentInfo = new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone())); string certSubjectName; byte[] encodedMessage; 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); 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); }
public static void AlgorithmIdentifierNullaryCtor() { AlgorithmIdentifier a = new AlgorithmIdentifier(); Assert.Equal(Oids.TripleDesCbc, a.Oid.Value); Assert.Equal(0, a.KeyLength); }
internal PublicKeyInfo (CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { m_algorithm = new AlgorithmIdentifier(keyInfo); m_keyValue = new byte[keyInfo.PublicKey.cbData]; if (m_keyValue.Length > 0) { Marshal.Copy(keyInfo.PublicKey.pbData, m_keyValue, 0, m_keyValue.Length); } }
public void ConstructorContentInfoAlgorithmIdentifier () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ContentInfo ci = new ContentInfo (asnNull); EnvelopedCms ep = new EnvelopedCms (ci, ai); DefaultProperties (ep, 2, 0); }
public void ConstructorContentInfoNullAlgorithmIdentifier () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); EnvelopedCms ep = new EnvelopedCms (null, ai); }
public void ConstructorSubjectIdentifierTypeIssuerAndSerialNumberContentInfoAlgorithmIdentifier () { AlgorithmIdentifier ai = new AlgorithmIdentifier (); ContentInfo ci = new ContentInfo (asnNull); EnvelopedCms ep = new EnvelopedCms (SubjectIdentifierType.IssuerAndSerialNumber, ci, ai); DefaultProperties (ep, 2, 0); }