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");
		}
Example #6
0
 /// <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;
		}
Example #8
0
		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");
		}
Example #10
0
        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;
 }
Example #14
0
        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();
 }
Example #19
0
		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");
		}
Example #24
0
        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;
        }
Example #25
0
        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);
        }
Example #26
0
        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);
        }
Example #27
0
 public static void AlgorithmIdentifierNullaryCtor()
 {
     AlgorithmIdentifier a = new AlgorithmIdentifier();
     Assert.Equal(Oids.TripleDesCbc, a.Oid.Value);
     Assert.Equal(0, a.KeyLength);
 }
Example #28
0
 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);
     }
 }
Example #29
0
		public void ConstructorContentInfoAlgorithmIdentifier () 
		{
			AlgorithmIdentifier ai = new AlgorithmIdentifier ();
			ContentInfo ci = new ContentInfo (asnNull);
			EnvelopedCms ep = new EnvelopedCms (ci, ai);
			DefaultProperties (ep, 2, 0);
		}
Example #30
0
		public void ConstructorContentInfoNullAlgorithmIdentifier () 
		{
			AlgorithmIdentifier ai = new AlgorithmIdentifier ();
			EnvelopedCms ep = new EnvelopedCms (null, ai);
		}
Example #31
0
		public void ConstructorSubjectIdentifierTypeIssuerAndSerialNumberContentInfoAlgorithmIdentifier () 
		{
			AlgorithmIdentifier ai = new AlgorithmIdentifier ();
			ContentInfo ci = new ContentInfo (asnNull);
			EnvelopedCms ep = new EnvelopedCms (SubjectIdentifierType.IssuerAndSerialNumber, ci, ai);
			DefaultProperties (ep, 2, 0);
		}