private static void EncodeDecode(
            byte[] certBytes,
            X509SubjectKeyIdentifierHashAlgorithm algorithm,
            bool critical,
            byte[] expectedDer,
            string expectedIdentifier)
        {
            PublicKey pk;

            using (var cert = new X509Certificate2(certBytes))
            {
                pk = cert.PublicKey;
            }

            X509SubjectKeyIdentifierExtension ext =
                new X509SubjectKeyIdentifierExtension(pk, algorithm, critical);

            byte[] rawData = ext.RawData;
            Assert.Equal(expectedDer, rawData);

            ext = new X509SubjectKeyIdentifierExtension(new AsnEncodedData(rawData), critical);
            Assert.Equal(expectedIdentifier, ext.SubjectKeyIdentifier);
            Assert.Equal(expectedIdentifier, Convert.ToHexString(ext.SubjectKeyIdentifierBytes.Span));

            ReadOnlyMemory <byte> ski1 = ext.SubjectKeyIdentifierBytes;
            ReadOnlyMemory <byte> ski2 = ext.SubjectKeyIdentifierBytes;

            Assert.True(ski1.Span == ski2.Span, "Two calls to SubjectKeyIdentifierBytes return the same buffer");
        }
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
 {
   Contract.Requires(key.EncodedKeyValue != null);
   Contract.Requires(key.EncodedKeyValue.RawData != null);
   Contract.Requires(key.EncodedParameters != null);
   Contract.Requires(key.EncodedParameters.RawData != null);
   Contract.Ensures(key.EncodedParameters.RawData != null);
 }
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
 {
     Contract.Requires(key.EncodedKeyValue != null);
     Contract.Requires(key.EncodedKeyValue.RawData != null);
     Contract.Requires(key.EncodedParameters != null);
     Contract.Requires(key.EncodedParameters.RawData != null);
     Contract.Ensures(key.EncodedParameters.RawData != null);
 }
        private static byte[] EncodeExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            byte[] subjectKeyIdentifier = GenerateSubjectKeyIdentifierFromPublicKey(key, algorithm);
            return(EncodeExtension(subjectKeyIdentifier));
        }
        public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            byte[] pkraw = key.EncodedKeyValue.RawData;
            // compute SKI
            switch (algorithm)
            {
            // hash of the public key, excluding Tag, Length and unused bits values
            case X509SubjectKeyIdentifierHashAlgorithm.Sha1:
                _subjectKeyIdentifier = SHA1.Create().ComputeHash(pkraw);
                break;

            // 0100 bit pattern followed by the 60 last bit of the hash
            case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1:
                byte[] hash = SHA1.Create().ComputeHash(pkraw);
                _subjectKeyIdentifier = new byte [8];
                Buffer.BlockCopy(hash, 12, _subjectKeyIdentifier, 0, 8);
                _subjectKeyIdentifier [0] = (byte)(0x40 | (_subjectKeyIdentifier [0] & 0x0F));
                break;

            // hash of the public key, including Tag, Length and unused bits values
            case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1:
                // CryptoAPI does that hash on the complete subjectPublicKeyInfo (unlike PKIX)
                // http://groups.google.ca/groups?selm=e7RqM%24plCHA.1488%40tkmsftngp02&oe=UTF-8&output=gplain
                ASN1 subjectPublicKeyInfo = new ASN1(0x30);
                ASN1 algo = subjectPublicKeyInfo.Add(new ASN1(0x30));
                algo.Add(new ASN1(CryptoConfig.EncodeOID(key.Oid.Value)));
                algo.Add(new ASN1(key.EncodedParameters.RawData));
                // add an extra byte for the unused bits (none)
                byte[] full = new byte [pkraw.Length + 1];
                Buffer.BlockCopy(pkraw, 0, full, 1, pkraw.Length);
                subjectPublicKeyInfo.Add(new ASN1(0x03, full));
                _subjectKeyIdentifier = SHA1.Create().ComputeHash(subjectPublicKeyInfo.GetBytes());
                break;

            default:
                throw new ArgumentException("algorithm");
            }

            _oid          = new Oid(oid, friendlyName);
            base.Critical = critical;
            RawData       = Encode();
        }
Exemplo n.º 6
0
        private static void TestSubjectKeyIdentifierExtension(
            byte[] certBytes,
            X509SubjectKeyIdentifierHashAlgorithm algorithm,
            bool critical,
            byte[] expectedDer,
            string expectedIdentifier)
        {
            PublicKey pk = new X509Certificate2(certBytes).PublicKey;

            X509SubjectKeyIdentifierExtension ext =
                new X509SubjectKeyIdentifierExtension(pk, algorithm, critical);

            byte[] rawData = ext.RawData;
            Assert.Equal(expectedDer, rawData);

            ext = new X509SubjectKeyIdentifierExtension(new AsnEncodedData(rawData), critical);
            Assert.Equal(expectedIdentifier, ext.SubjectKeyIdentifier);
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension" /> class using a public key, a hash algorithm identifier, and a value indicating whether the extension is critical. </summary>
        /// <param name="key">A <see cref="T:System.Security.Cryptography.X509Certificates.PublicKey" /> object to create a subject key identifier (SKI) from.</param>
        /// <param name="algorithm">One of the <see cref="T:System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierHashAlgorithm" /> values that identifies which hash algorithm to use.</param>
        /// <param name="critical">true if the extension is critical; otherwise, false.</param>
        public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            byte[] rawData = key.EncodedKeyValue.RawData;
            switch (algorithm)
            {
            case X509SubjectKeyIdentifierHashAlgorithm.Sha1:
                this._subjectKeyIdentifier = SHA1.Create().ComputeHash(rawData);
                break;

            case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1:
            {
                byte[] src = SHA1.Create().ComputeHash(rawData);
                this._subjectKeyIdentifier = new byte[8];
                Buffer.BlockCopy(src, 12, this._subjectKeyIdentifier, 0, 8);
                this._subjectKeyIdentifier[0] = (64 | (this._subjectKeyIdentifier[0] & 15));
                break;
            }

            case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1:
            {
                ASN1 asn  = new ASN1(48);
                ASN1 asn2 = asn.Add(new ASN1(48));
                asn2.Add(new ASN1(CryptoConfig.EncodeOID(key.Oid.Value)));
                asn2.Add(new ASN1(key.EncodedParameters.RawData));
                byte[] array = new byte[rawData.Length + 1];
                Buffer.BlockCopy(rawData, 0, array, 1, rawData.Length);
                asn.Add(new ASN1(3, array));
                this._subjectKeyIdentifier = SHA1.Create().ComputeHash(asn.GetBytes());
                break;
            }

            default:
                throw new ArgumentException("algorithm");
            }
            this._oid     = new Oid("2.5.29.14", "Subject Key Identifier");
            base.Critical = critical;
            base.RawData  = this.Encode();
        }
Exemplo n.º 8
0
 public X509SubjectKeyIdentifierExtension (PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) :
     base (CAPI.szOID_SUBJECT_KEY_IDENTIFIER, EncodePublicKey(key, algorithm), critical) {}
Exemplo n.º 9
0
        private static unsafe byte[] EncodePublicKey (PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm) {
            if (key == null)
                throw new ArgumentNullException("key");

            // Construct CERT_PUBLIC_KEY_INFO2 in unmanged memory from given encoded blobs.
            SafeLocalAllocHandle publicKeyInfo = EncodePublicKey(key);
            CAPI.CERT_PUBLIC_KEY_INFO2 * pPublicKeyInfo = (CAPI.CERT_PUBLIC_KEY_INFO2 *) publicKeyInfo.DangerousGetHandle();

            byte [] buffer = new byte[20];
            byte [] identifier = null;

            fixed (byte * pBuffer = buffer) {
                uint cbData = (uint)buffer.Length;
                IntPtr pbData = new IntPtr(pBuffer);

                try {
                    if ((X509SubjectKeyIdentifierHashAlgorithm.Sha1 == algorithm) 
                        || (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm)) {
                    //+=================================================================
                    // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of 
                    // the value of the BIT STRING subjectPublicKey (excluding the tag,
                    // length, and number of unused bits).
                        if (!CAPI.CryptHashCertificate(
                                    IntPtr.Zero,        // hCryptProv
                                    CAPI.CALG_SHA1,
                                    0,                  // dwFlags,
                                    pPublicKeyInfo->PublicKey.pbData,
                                    pPublicKeyInfo->PublicKey.cbData,
                                    pbData,
                                    new IntPtr(&cbData)))
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                    }
                    //+=================================================================
                    // Microsoft convention: The keyIdentifier is composed of the 
                    // 160-bit SHA-1 hash of the encoded subjectPublicKey BITSTRING 
                    // (including the tag, length, and number of unused bits).
                    else if (X509SubjectKeyIdentifierHashAlgorithm.CapiSha1 == algorithm) {
                        if (!CAPI.CryptHashPublicKeyInfo(
                                    IntPtr.Zero,        // hCryptProv
                                    CAPI.CALG_SHA1,
                                    0,                  // dwFlags,
                                    CAPI.X509_ASN_ENCODING,
                                    new IntPtr(pPublicKeyInfo),
                                    pbData,
                                    new IntPtr(&cbData))) {
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                        }
                    } else {
                        throw new ArgumentException("algorithm");
                    }

                    //+=================================================================
                    // (2) The keyIdentifier is composed of a four bit type field with
                    //  the value 0100 followed by the least significant 60 bits of the
                    //  SHA-1 hash of the value of the BIT STRING subjectPublicKey 
                    // (excluding the tag, length, and number of unused bit string bits)
                    if (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm) {
                        identifier = new byte[8];
                        Array.Copy(buffer, buffer.Length - 8, identifier, 0, identifier.Length);
                        identifier[0] &= 0x0f;
                        identifier[0] |= 0x40;
                    } else {
                        identifier = buffer;
                        // return the meaningful part only
                        if (buffer.Length > (int)cbData) {
                            identifier = new byte[cbData];
                            Array.Copy(buffer, 0, identifier, 0, identifier.Length);
                        }
                    }
                } finally {
                    publicKeyInfo.Dispose();
                }
            }

            return EncodeExtension(identifier);
        }
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical);
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) : base("2.5.29.14", EncodePublicKey(key, algorithm), critical)
 {
 }
Exemplo n.º 12
0
        private static unsafe byte[] EncodePublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            // Construct CERT_PUBLIC_KEY_INFO2 in unmanged memory from given encoded blobs.
            SafeLocalAllocHandle publicKeyInfo = EncodePublicKey(key);

            CAPI.CERT_PUBLIC_KEY_INFO2 *pPublicKeyInfo = (CAPI.CERT_PUBLIC_KEY_INFO2 *)publicKeyInfo.DangerousGetHandle();

            byte [] buffer     = new byte[20];
            byte [] identifier = null;

            fixed(byte *pBuffer = buffer)
            {
                uint   cbData = (uint)buffer.Length;
                IntPtr pbData = new IntPtr(pBuffer);

                try {
                    if ((X509SubjectKeyIdentifierHashAlgorithm.Sha1 == algorithm) ||
                        (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm))
                    {
                        //+=================================================================
                        // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of
                        // the value of the BIT STRING subjectPublicKey (excluding the tag,
                        // length, and number of unused bits).
                        if (!CAPI.CryptHashCertificate(
                                IntPtr.Zero,            // hCryptProv
                                CAPI.CALG_SHA1,
                                0,                      // dwFlags,
                                pPublicKeyInfo->PublicKey.pbData,
                                pPublicKeyInfo->PublicKey.cbData,
                                pbData,
                                new IntPtr(&cbData)))
                        {
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                        }
                    }
                    //+=================================================================
                    // Microsoft convention: The keyIdentifier is composed of the
                    // 160-bit SHA-1 hash of the encoded subjectPublicKey BITSTRING
                    // (including the tag, length, and number of unused bits).
                    else if (X509SubjectKeyIdentifierHashAlgorithm.CapiSha1 == algorithm)
                    {
                        if (!CAPI.CryptHashPublicKeyInfo(
                                IntPtr.Zero,            // hCryptProv
                                CAPI.CALG_SHA1,
                                0,                      // dwFlags,
                                CAPI.X509_ASN_ENCODING,
                                new IntPtr(pPublicKeyInfo),
                                pbData,
                                new IntPtr(&cbData)))
                        {
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                        }
                    }
                    else
                    {
                        throw new ArgumentException("algorithm");
                    }

                    //+=================================================================
                    // (2) The keyIdentifier is composed of a four bit type field with
                    //  the value 0100 followed by the least significant 60 bits of the
                    //  SHA-1 hash of the value of the BIT STRING subjectPublicKey
                    // (excluding the tag, length, and number of unused bit string bits)
                    if (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm)
                    {
                        identifier = new byte[8];
                        Array.Copy(buffer, buffer.Length - 8, identifier, 0, identifier.Length);
                        identifier[0] &= 0x0f;
                        identifier[0] |= 0x40;
                    }
                    else
                    {
                        identifier = buffer;
                        // return the meaningful part only
                        if (buffer.Length > (int)cbData)
                        {
                            identifier = new byte[cbData];
                            Array.Copy(buffer, 0, identifier, 0, identifier.Length);
                        }
                    }
                } finally {
                    publicKeyInfo.Dispose();
                }
            }

            return(EncodeExtension(identifier));
        }
		public X509SubjectKeyIdentifierExtension (PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
		{
			if (key == null)
				throw new ArgumentNullException ("key");

			byte[] pkraw = key.EncodedKeyValue.RawData;
			// compute SKI
			switch (algorithm) {
			// hash of the public key, excluding Tag, Length and unused bits values
			case X509SubjectKeyIdentifierHashAlgorithm.Sha1:
				_subjectKeyIdentifier = SHA1.Create ().ComputeHash (pkraw);
				break;
			// 0100 bit pattern followed by the 60 last bit of the hash
			case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1:
				byte[] hash = SHA1.Create ().ComputeHash (pkraw);
				_subjectKeyIdentifier = new byte [8];
				Buffer.BlockCopy (hash, 12, _subjectKeyIdentifier, 0, 8);
				_subjectKeyIdentifier [0] = (byte) (0x40 | (_subjectKeyIdentifier [0] & 0x0F));
				break;
			// hash of the public key, including Tag, Length and unused bits values
			case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1:
				// CryptoAPI does that hash on the complete subjectPublicKeyInfo (unlike PKIX)
				// http://groups.google.ca/groups?selm=e7RqM%24plCHA.1488%40tkmsftngp02&oe=UTF-8&output=gplain
				ASN1 subjectPublicKeyInfo = new ASN1 (0x30);
				ASN1 algo = subjectPublicKeyInfo.Add (new ASN1 (0x30));
				algo.Add (new ASN1 (CryptoConfig.EncodeOID (key.Oid.Value)));
				algo.Add (new ASN1 (key.EncodedParameters.RawData)); 
				// add an extra byte for the unused bits (none)
				byte[] full = new byte [pkraw.Length + 1];
				Buffer.BlockCopy (pkraw, 0, full, 1, pkraw.Length);
				subjectPublicKeyInfo.Add (new ASN1 (0x03, full));
				_subjectKeyIdentifier = SHA1.Create ().ComputeHash (subjectPublicKeyInfo.GetBytes ());
				break;
			default:
				throw new ArgumentException ("algorithm");
			}

			_oid = new Oid (oid, friendlyName);
			base.Critical = critical;
			RawData = Encode ();
		}
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) : base("2.5.29.14", EncodePublicKey(key, algorithm), critical)
 {
 }
Exemplo n.º 15
0
        private static void TestSubjectKeyIdentifierExtension(
            byte[] certBytes,
            X509SubjectKeyIdentifierHashAlgorithm algorithm,
            bool critical,
            byte[] expectedDer,
            string expectedIdentifier)
        {
            PublicKey pk = new X509Certificate2(certBytes).PublicKey;

            X509SubjectKeyIdentifierExtension ext =
                new X509SubjectKeyIdentifierExtension(pk, algorithm, critical);

            byte[] rawData = ext.RawData;
            Assert.Equal(expectedDer, rawData);

            ext = new X509SubjectKeyIdentifierExtension(new AsnEncodedData(rawData), critical);
            Assert.Equal(expectedIdentifier, ext.SubjectKeyIdentifier);
        }
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
     : base(Oids.SubjectKeyIdentifier, EncodeExtension(key, algorithm), critical)
 {
 }
 private static unsafe byte[] EncodePublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     SafeLocalAllocHandle handle = EncodePublicKey(key);
     CAPIBase.CERT_PUBLIC_KEY_INFO2* cert_public_key_infoPtr = (CAPIBase.CERT_PUBLIC_KEY_INFO2*) handle.DangerousGetHandle();
     byte[] sourceArray = new byte[20];
     byte[] destinationArray = null;
     fixed (byte* numRef = sourceArray)
     {
         uint length = (uint) sourceArray.Length;
         IntPtr pbComputedHash = new IntPtr((void*) numRef);
         try
         {
             if ((algorithm == X509SubjectKeyIdentifierHashAlgorithm.Sha1) || (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm))
             {
                 if (!CAPISafe.CryptHashCertificate(IntPtr.Zero, 0x8004, 0, cert_public_key_infoPtr->PublicKey.pbData, cert_public_key_infoPtr->PublicKey.cbData, pbComputedHash, new IntPtr((void*) &length)))
                 {
                     throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                 }
             }
             else
             {
                 if (X509SubjectKeyIdentifierHashAlgorithm.CapiSha1 != algorithm)
                 {
                     throw new ArgumentException("algorithm");
                 }
                 if (!CAPISafe.CryptHashPublicKeyInfo(IntPtr.Zero, 0x8004, 0, 1, new IntPtr((void*) cert_public_key_infoPtr), pbComputedHash, new IntPtr((void*) &length)))
                 {
                     throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                 }
             }
             if (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm)
             {
                 destinationArray = new byte[8];
                 Array.Copy(sourceArray, sourceArray.Length - 8, destinationArray, 0, destinationArray.Length);
                 destinationArray[0] = (byte) (destinationArray[0] & 15);
                 destinationArray[0] = (byte) (destinationArray[0] | 0x40);
             }
             else
             {
                 destinationArray = sourceArray;
                 if (sourceArray.Length > length)
                 {
                     destinationArray = new byte[length];
                     Array.Copy(sourceArray, 0, destinationArray, 0, destinationArray.Length);
                 }
             }
         }
         finally
         {
             handle.Dispose();
         }
     }
     return EncodeExtension(destinationArray);
 }
Exemplo n.º 18
0
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
 {
 }
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
     : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(key, algorithm), critical)
 {
 }
        private static byte[] GenerateSubjectKeyIdentifierFromPublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            switch (algorithm)
            {
            case X509SubjectKeyIdentifierHashAlgorithm.Sha1:
                return(SHA1.HashData(key.EncodedKeyValue.RawData));

            case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1:
            {
                byte[] sha1 = SHA1.HashData(key.EncodedKeyValue.RawData);

                //  ShortSha1: The keyIdentifier is composed of a four bit type field with
                //  the value 0100 followed by the least significant 60 bits of the
                //  SHA-1 hash of the value of the BIT STRING subjectPublicKey
                // (excluding the tag, length, and number of unused bit string bits)
                byte[] shortSha1 = new byte[8];
                Buffer.BlockCopy(sha1, sha1.Length - 8, shortSha1, 0, shortSha1.Length);
                shortSha1[0] &= 0x0f;
                shortSha1[0] |= 0x40;
                return(shortSha1);
            }

            case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1:
                return(X509Pal.Instance.ComputeCapiSha1OfPublicKey(key));

            default:
                throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, algorithm), nameof(algorithm));
            }
        }
        private static byte[] EncodeExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            if (key == null)
                throw new ArgumentNullException(nameof(key));

            byte[] subjectKeyIdentifier = GenerateSubjectKeyIdentifierFromPublicKey(key, algorithm);
            return EncodeExtension(subjectKeyIdentifier);
        }
Exemplo n.º 22
0
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) :
     base(CAPI.szOID_SUBJECT_KEY_IDENTIFIER, EncodePublicKey(key, algorithm), critical)
 {
 }
        private static byte[] GenerateSubjectKeyIdentifierFromPublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            switch (algorithm)
            {
                case X509SubjectKeyIdentifierHashAlgorithm.Sha1:
                    return ComputeSha1(key.EncodedKeyValue.RawData);

                case X509SubjectKeyIdentifierHashAlgorithm.ShortSha1:
                    {
                        byte[] sha1 = ComputeSha1(key.EncodedKeyValue.RawData);

                        //  ShortSha1: The keyIdentifier is composed of a four bit type field with
                        //  the value 0100 followed by the least significant 60 bits of the
                        //  SHA-1 hash of the value of the BIT STRING subjectPublicKey
                        // (excluding the tag, length, and number of unused bit string bits)
                        byte[] shortSha1 = new byte[8];
                        Buffer.BlockCopy(sha1, sha1.Length - 8, shortSha1, 0, shortSha1.Length);
                        shortSha1[0] &= 0x0f;
                        shortSha1[0] |= 0x40;
                        return shortSha1;
                    }

                case X509SubjectKeyIdentifierHashAlgorithm.CapiSha1:
                    return X509Pal.Instance.ComputeCapiSha1OfPublicKey(key);

                default:
                    throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, algorithm), nameof(algorithm));
            }
        }
		public X509SubjectKeyIdentifierExtension (PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
		{
			if (key == null)
				throw new ArgumentNullException ("key");
		}
        private static unsafe byte[] EncodePublicKey(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            SafeLocalAllocHandle handle = EncodePublicKey(key);

            CAPIBase.CERT_PUBLIC_KEY_INFO2 *cert_public_key_infoPtr = (CAPIBase.CERT_PUBLIC_KEY_INFO2 *)handle.DangerousGetHandle();
            byte[] sourceArray      = new byte[20];
            byte[] destinationArray = null;
            fixed(byte *numRef = sourceArray)
            {
                uint   length         = (uint)sourceArray.Length;
                IntPtr pbComputedHash = new IntPtr((void *)numRef);

                try
                {
                    if ((algorithm == X509SubjectKeyIdentifierHashAlgorithm.Sha1) || (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm))
                    {
                        if (!CAPISafe.CryptHashCertificate(IntPtr.Zero, 0x8004, 0, cert_public_key_infoPtr->PublicKey.pbData, cert_public_key_infoPtr->PublicKey.cbData, pbComputedHash, new IntPtr((void *)&length)))
                        {
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                        }
                    }
                    else
                    {
                        if (X509SubjectKeyIdentifierHashAlgorithm.CapiSha1 != algorithm)
                        {
                            throw new ArgumentException("algorithm");
                        }
                        if (!CAPISafe.CryptHashPublicKeyInfo(IntPtr.Zero, 0x8004, 0, 1, new IntPtr((void *)cert_public_key_infoPtr), pbComputedHash, new IntPtr((void *)&length)))
                        {
                            throw new CryptographicException(Marshal.GetHRForLastWin32Error());
                        }
                    }
                    if (X509SubjectKeyIdentifierHashAlgorithm.ShortSha1 == algorithm)
                    {
                        destinationArray = new byte[8];
                        Array.Copy(sourceArray, sourceArray.Length - 8, destinationArray, 0, destinationArray.Length);
                        destinationArray[0] = (byte)(destinationArray[0] & 15);
                        destinationArray[0] = (byte)(destinationArray[0] | 0x40);
                    }
                    else
                    {
                        destinationArray = sourceArray;
                        if (sourceArray.Length > length)
                        {
                            destinationArray = new byte[length];
                            Array.Copy(sourceArray, 0, destinationArray, 0, destinationArray.Length);
                        }
                    }
                }
                finally
                {
                    handle.Dispose();
                }
            }

            return(EncodeExtension(destinationArray));
        }
Exemplo n.º 26
0
 public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical)
 {
     throw new NotImplementedException();
 }