Пример #1
0
        public CngKey Build()
        {
            if (_theReader.First().Header == "PUBLIC KEY")
            {
                using (var ms = new MemoryStream(_theReader.First().Body))
                    using (var br = new BinaryReader(ms))
                    {
                        // should have a sequence
                        br.Require(Asn1Token.Sequence);
                        // ignore the length
                        br.ReadLengthField();

                        // should have an inner sequence
                        br.Require(Asn1Token.Sequence);
                        // ignore the length
                        br.ReadLengthField();

                        //should have an OID
                        br.Require(Asn1Token.Oid);
                        // get its length
                        int oidLength = br.ReadByte();
                        var oid       = Asn1Token.GetOid(br.ReadBytes(oidLength));
                        var builder   = GetBuilderFor(oid);
                        return(builder.Build(br));
                    }
            }
            throw new NotImplementedException();
        }
Пример #2
0
 private CngKeyBuilderImpl GetBuilderFor(Asn1Token.KnownOid oid)
 {
     switch(oid)
     {
         case Asn1Token.KnownOid.EcPublicKey:
             return new EllipticCurveCngKeyBuilder();
         case Asn1Token.KnownOid.RsaEncryptionPkcs1:
             return new RsaCngKeyBuilder();
     }
     throw new UnsupportedCurveException("Unsupported key type with oid");
 }
Пример #3
0
            public override CngKey Build(BinaryReader reader)
            {
                reader.Require(Asn1Token.Oid);
                var length = reader.ReadLengthField();
                var curve  = Asn1Token.GetOid(reader.ReadBytes(length));

                if (!isSupportedCurve(curve))
                {
                    throw new UnsupportedCurveException("Unsupported curve oid");
                }

                // We need to build a key blob structured as follows:
                //     BCRYPT_ECCKEY_BLOB   header
                //     byte[cbPublicExp]    publicExponent      - Exponent
                //     byte[cbModulus]      modulus             - Modulus
                //     -- Private only --
                //     byte[cbPrime1]       prime1              - P
                //     byte[cbPrime2]       prime2              - Q
                //

                // Where
                // typedef struct _BCRYPT_ECCKEY_BLOB {
                //  ULONG Magic; //BCRYPT_ECDSA_PUBLIC_P256_MAGIC =  0x31534345
                //  ULONG cbKey; // Key length in bytes
                //} B

                reader.Require(Asn1Token.BitString);
                var keyLength = reader.ReadLengthField() - 2;

                //ignore the zero byte
                reader.Require(0x00);

                // if this isn't an uncompressed curve, then panic
                reader.Require(0x04);

                var x = reader.ReadBytes(keyLength / 2);
                var y = reader.ReadBytes(keyLength / 2);

                return(BuildEcKey(x, y, curve));
            }
Пример #4
0
            private unsafe CngKey BuildEcKey(byte[] x, byte[] y, Asn1Token.KnownOid curve)
            {
                int headerSize = Marshal.SizeOf(typeof (BCRYPT_ECCKEY_BLOB));
                int blobSize = headerSize + x.Length + y.Length;
                byte[] blobBytes = new byte[blobSize];

                fixed(byte* pBlobBytes = blobBytes)
                {
                BCRYPT_ECCKEY_BLOB* pBcryptEccBlob = (BCRYPT_ECCKEY_BLOB*) pBlobBytes;
                pBcryptEccBlob->KeyBlobMagicNumber = GetMagicNumber(curve);
                pBcryptEccBlob->KeySizeBytes = x.Length;

                Buffer.BlockCopy(x, 0, blobBytes, headerSize, x.Length);
                Buffer.BlockCopy(y, 0, blobBytes, headerSize+x.Length, y.Length);
                }

                new KeyContainerPermission(KeyContainerPermissionFlags.Import).Assert();
                var key = CngKey.Import(blobBytes, CngKeyBlobFormat.EccPublicBlob);
                CodeAccessPermission.RevertAssert();
                return key;
            }
Пример #5
0
 private static bool isSupportedCurve(Asn1Token.KnownOid curve)
 {
     return curve == Asn1Token.KnownOid.AnsiX9P256R1 ||
        curve == Asn1Token.KnownOid.Secp384R1    ||
        curve == Asn1Token.KnownOid.Secp521R1;
 }
Пример #6
0
 private static int GetMagicNumber(Asn1Token.KnownOid curve)
 {
     switch(curve)
     {
         case Asn1Token.KnownOid.AnsiX9P256R1:
             return 0x31534345;
         case Asn1Token.KnownOid.Secp384R1:
             return 0x33534345;
         case Asn1Token.KnownOid.Secp521R1:
             return 0x35534345;
     }
     throw new UnsupportedCurveException("Unsupported elliptic curve domain");
 }