Exemple #1
0
        public byte[] ToDER(bool compressed)
        {
            AssertPrivateKey();
            MemoryStream baos = new MemoryStream();

            // ASN1_SEQUENCE(EC_PRIVATEKEY) = {
            //   ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
            //   ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
            //   ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
            //   ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
            // } ASN1_SEQUENCE_END(EC_PRIVATEKEY)
            DerSequenceGenerator seq = new DerSequenceGenerator(baos);

            seq.AddObject(new DerInteger(1));             // version
            seq.AddObject(new DerOctetString(PrivateKey.D.ToByteArrayUnsigned()));


            //Did not managed to generate the same der as brainwallet by using this
            //seq.AddObject(new DerTaggedObject(0, Secp256k1.ToAsn1Object()));
            Asn1Object secp256k1Der = null;

            if (compressed)
            {
                secp256k1Der = DerSequence.FromByteArray(DataEncoders.Encoders.Hex.DecodeData("308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101"));
            }
            else
            {
                secp256k1Der = DerSequence.FromByteArray(DataEncoders.Encoders.Hex.DecodeData("3081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101"));
            }
            seq.AddObject(new DerTaggedObject(0, secp256k1Der));
            seq.AddObject(new DerTaggedObject(1, new DerBitString(GetPubKey(compressed).ToBytes())));
            seq.Close();
            return(baos.ToArray());
        }
Exemple #2
0
        /// <summary>
        /// Parses and checks contents of the DICE extension
        /// </summary>
        /// <param name="c">Certificate to validate</param>
        /// <returns>Extension is well formed</returns>
        bool CheckDICEExtension(X509Certificate c)
        {
            var criticalOids = c.GetCriticalExtensionOids();

            if (criticalOids.Contains(DICEExtensionOid))
            {
                Error("DICE extension is marked critical and should be non-critical");
                return(false);
            }

            var nonCriticalOids = c.GetNonCriticalExtensionOids();

            if (!nonCriticalOids.Contains(DICEExtensionOid))
            {
                Error("DICE extension not found");
                return(false);
            }
            var diceExtension = c.GetExtensionValue(new DerObjectIdentifier(DICEExtensionOid));

            try
            {
                DerOctetString envelope = (DerOctetString)DerOctetString.FromByteArray(diceExtension.GetEncoded());
                DerSequence    seq      = (DerSequence)DerSequence.FromByteArray(envelope.GetOctets());
                // first field is version number
                var versionNumber = (DerInteger)seq[0];
                if (versionNumber.PositiveValue.IntValue != 1)
                {
                    Error($"DICE Extension has Wrong version number.  Expecing {DICEExtensionVersionNumber}, cert contains {versionNumber.ToString()}");
                    return(false);
                }
                // second field is DeviceID
                var devIdPubKey = SubjectPublicKeyInfo.GetInstance(seq[1]);
                // will check it's good later
                PubKeyInfoFromDICEExtension = devIdPubKey;

                // third field contains {hashOid, hashVal}
                var hashEnvelope = (DerSequence)seq[2];
                var hashAlg      = (DerObjectIdentifier)hashEnvelope[0];
                if (hashAlg.Id != NistObjectIdentifiers.IdSha256.ToString())
                {
                    Error("DICE Extension hash alg is wrong.  ");
                    return(false);
                }
                var hashVal = (DerOctetString)hashEnvelope[1];
                if (hashVal.GetOctets().Length != 32)
                {
                    Error("DICE Extension hash value length is wrong.  ");
                    return(false);
                }
            }
            catch (Exception e)
            {
                Error($"Failed to parse the DICE extension.  Parsing exception was {e.ToString()}");
                return(false);
            }

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Parses the AddedTo data that is returned from TPM2_CertifyX509()
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static AddedToCertificate FromDerEncoding(byte[] data)
        {
            var ret           = new AddedToCertificate();
            var sequence      = (DerSequence)DerSequence.FromByteArray(data);
            var taggedVersion = (DerTaggedObject)(sequence[0]);

            Debug.Assert(taggedVersion.TagNo == 0);
            ret.Version              = (DerInteger)taggedVersion.GetObject();
            ret.SerialNumber         = (DerInteger)sequence[1];
            ret.Signature            = AlgorithmIdentifier.GetInstance(sequence[2]);
            ret.SubjectPublicKeyInfo = SubjectPublicKeyInfo.GetInstance(sequence[3]);
            return(ret);
        }
Exemple #4
0
        /// <summary>
        /// If a device presents a "bare" certificate rather than a full certificate chain, we have to
        /// peform some steps that would normall be performed by the X509 chain builder.  Specifically,
        /// the RIoT extension (above) encodes the DeviceID public key, but we have to check that this
        /// Alias Cert was actually signed by the corresponding DeviceID private key.  To do this we
        /// parse the Alias Cert to get:
        ///     The "to be signed" region (byte array)
        ///     The OID of the signature scheme
        ///     The signature block
        ///
        /// The caller of this function can then check that the ALias Cert was indeed signed by the
        /// device it claims to be from.
        /// </summary>
        /// <param name="aliasCert"></param>
        /// <returns></returns>
        static internal DecomposedCert Decompose(X509Certificate2 aliasCert)
        {
            var rawData = aliasCert.GetRawCertData();

            try
            {
                DerSequence seq       = (DerSequence)DerSequence.FromByteArray(rawData);
                DerSequence tbs       = (DerSequence)seq[0];
                DerSequence sigAlg    = (DerSequence)seq[1];
                var         sigAlgOid = (DerObjectIdentifier)sigAlg[0];

                DerBitString sigData     = (DerBitString)seq[2];
                DerSequence  sigSequence = (DerSequence)DerSequence.FromByteArray(sigData.GetOctets());
                var          sig1        = (DerInteger)sigSequence[0];
                var          sig2        = (DerInteger)sigSequence[0];

                var sig1Bytes = sig1.Value.ToByteArrayUnsigned();
                var sig2Bytes = sig1.Value.ToByteArrayUnsigned();

                Debug.Assert(sig1Bytes.Length == 32 && sig1Bytes.Length == 32);

                byte[] SignatureX = new byte[64];
                Array.Copy(sig1Bytes, 0, SignatureX, 0, 32);
                Array.Copy(sig2Bytes, 0, SignatureX, 32, 32);

                Debug.WriteLine("");

                DecomposedCert bits = new DecomposedCert
                {
                    Tbs       = tbs.GetDerEncoded(),
                    OID       = sigAlgOid.Id,
                    Signature = SignatureX
                };
                return(bits);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
                return(null);
            }
        }
Exemple #5
0
        static internal RIoTDeviceInfo Decode(X509Certificate2 aliasCert)
        {
            AsnEncodedData altNames = null;

            foreach (var ext in aliasCert.Extensions)
            {
                if (ext.Oid.Value != RIoTOid)
                {
                    continue;
                }
                altNames = new AsnEncodedData(ext.Oid, ext.RawData);
            }
            // an AltName is mandatory
            if (altNames == null)
            {
                Helpers.Notify("Certificate does not have an altName field", true);
                return(null);
            }
            // parse the extension: this is a collection of nested thus -

            /*
             *  DER Sequence
             *      ObjectIdentifier(1.2.3.4.5.6)                               <- RIoT Composite ID OID
             *      DER Sequence
             *          Integer(1)                                              <- Version number
             *          DER Sequence                                            <- DeviceID public key
             *              DER Sequence                                            (same encoding as in DeviceID cert)
             *                  ObjectIdentifier(1.2.840.10045.2.1)                 EC pubkey
             *                  ObjectIdentifier(1.2.840.10045.3.1.7)               prime256
             *              DER Bit String[65, 0]                                   key value
             *          DER Sequence                                            <-  Encoded FWID
             *              ObjectIdentifier(2.16.840.1.101.3.4.2.1)                sha256
             *              DER Octet String[32]                                    FWID hash value
             *
             *
             * */

            try
            {
                DerSequence seq = (DerSequence)DerSequence.FromByteArray(altNames.RawData);
                //DerTaggedObject obj = (DerTaggedObject)seq[0];
                //DerSequence obj2 = (DerSequence)obj.GetObject();
                //var oid = (DerObjectIdentifier)obj2[0];
                //if (oid.Id != RIoTOid) return ParseError("Incorrect RIoT OID");


                var versionNumber = (DerInteger)seq[0];
                if (versionNumber.PositiveValue.IntValue != 1)
                {
                    return(ParseError("Wrong version number"));
                }

                DerSequence obj4    = (DerSequence)seq[1];
                DerSequence obj5    = (DerSequence)obj4[0];
                var         keyAlg1 = (DerObjectIdentifier)obj5[0];
                var         keyAlg2 = (DerObjectIdentifier)obj5[1];
                if (keyAlg1.Id != ecPubKeyOID)
                {
                    return(ParseError("Bad ECPubKey OID"));
                }
                if (keyAlg2.Id != prime256v1Oid)
                {
                    return(ParseError("Bad curve OID"));
                }
                var key     = (DerBitString)obj4[1];
                var obj4b   = (DerSequence)seq[2];
                var hashAlg = (DerObjectIdentifier)obj4b[0];
                if (hashAlg.Id != sha256Oid)
                {
                    return(ParseError("Bad fwid hash OID"));
                }
                var            hash       = (DerOctetString)obj4b[1];
                RIoTDeviceInfo deviceInfo = new RIoTDeviceInfo()
                {
                    FirmwareID         = hash.GetOctets(),
                    EncodedDeviceIDKey = key.GetBytes(),
                    Cert = aliasCert
                };

                return(deviceInfo);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
                return(null);
            }
        }
Exemple #6
0
        SimulateX509Certify(PartialCertificate partialCert, AsymmetricKeyParameter publicKeyToCertify,
                            AsymmetricKeyParameter signingKey, string signingAlgorithm)
        {
            // We can simulate ECDSA/SHA256 and RSA/SHA256

            ISignatureFactory   signatureFactory;
            DerObjectIdentifier sigAlgOid;

            if (signingKey is ECPrivateKeyParameters)
            {
                sigAlgOid = X9ObjectIdentifiers.ECDsaWithSha256;
            }
            else
            {
                sigAlgOid = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
            }


            //signatureFactory = new Asn1SignatureFactory(sigAlgOid.ToString(), signingKey);
            signatureFactory = new Asn1SignatureFactory(sigAlgOid.ToString(), signingKey);

            // Make the certificate
            var certGenerator = new X509V3CertificateGenerator();

            certGenerator.SetIssuerDN(partialCert.Issuer);
            certGenerator.SetSubjectDN(partialCert.Subject);
            certGenerator.SetSerialNumber(BigInteger.ValueOf(1));
            certGenerator.SetNotBefore(partialCert.NotBefore);
            certGenerator.SetNotAfter(partialCert.NotAfter);
            certGenerator.SetPublicKey(publicKeyToCertify);
            if (partialCert.SubjectUniqueId != null)
            {
                certGenerator.SetSubjectUniqueID(ByteArrayToBoolArray(partialCert.SubjectUniqueId));
            }
            if (partialCert.IssuerUniqueId != null)
            {
                certGenerator.SetIssuerUniqueID(ByteArrayToBoolArray(partialCert.IssuerUniqueId));
            }

            // process the extensions.  Note that this will not preserve the order
            var extensions = partialCert.Extensions;

            if (extensions != null)
            {
                foreach (var critExtOid in extensions.GetCriticalExtensionOids())
                {
                    certGenerator.AddExtension(critExtOid.ToString(), true, extensions.GetExtension(critExtOid).GetParsedValue());
                }
                foreach (var nonCritExtOid in extensions.GetNonCriticalExtensionOids())
                {
                    certGenerator.AddExtension(nonCritExtOid.ToString(), false, extensions.GetExtension(nonCritExtOid).GetParsedValue());
                }
            }

            // and sign to make the cert
            var cert = certGenerator.Generate(signatureFactory);

            // take things apart again for addedToCert
            var subjectPubKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKeyToCertify);

            // get the exact bytes for the signature algorithm
            var tbsSequence = ((DerSequence)DerSequence.FromByteArray(cert.GetTbsCertificate()));
            var sigAlgBytes = tbsSequence[2];

            AddedToCertificate addedTo = new AddedToCertificate()
            {
                Version              = new DerInteger(BigInteger.ValueOf(cert.Version)),
                SerialNumber         = new DerInteger(cert.SerialNumber),
                Signature            = AlgorithmIdentifier.GetInstance(sigAlgBytes),
                SubjectPublicKeyInfo = subjectPubKeyInfo
            };

            return(System.ValueTuple.Create(cert, addedTo));
        }
        public static CngKey Import(Byte[] blob,
                                    Int32 offset = 0)
        {
            Boolean isPrivateKey = false;
            Byte    keyLength    = 0;

            Byte[] keyCurveX = null, keyCurveY = null, keyScalar = null;
            Byte[] inBlob    = blob;

            // Apply offset to incoming data.
            if (offset > 0)
            {
                var blobLength = blob.Length - (offset);
                inBlob = new Byte[blobLength];
                Array.Copy(blob, offset, inBlob, 0, blobLength);
            }
            System.IO.File.WriteAllBytes("Key.key", inBlob);

            DerSequence der = (DerSequence)DerSequence.FromByteArray(inBlob);

            try {             /*to read directly*/
                isPrivateKey = ((DerBitString)der[0]).IntValue != 0;
            } catch {
                der = (DerSequence)DerSequence.FromByteArray(((DerOctetString)der[1]).GetOctets());
                System.IO.File.WriteAllBytes("KeyDer.key", der.GetEncoded());
            }

            // Read Data from Key.
            isPrivateKey = ((DerBitString)der[0]).IntValue != 0;
            keyLength    = (Byte)((DerInteger)der[1]).PositiveValue.IntValue;
            keyCurveX    = ((DerInteger)der[2]).PositiveValue.ToByteArrayUnsigned();
            keyCurveY    = ((DerInteger)der[3]).PositiveValue.ToByteArrayUnsigned();
            if (isPrivateKey)
            {
                keyScalar = ((DerInteger)der[4]).PositiveValue.ToByteArrayUnsigned();
            }

            // Validate data.
            if (keyLength == 0)
            {
                throw new IndexOutOfRangeException("Length of key is 0.");
            }
            if (keyCurveX == null || keyCurveY == null)
            {
                throw new IndexOutOfRangeException("Key Curve is not set.");
            }

            // Construct a readable key out of this data.
            Byte[] newBlob = new Byte[8 + (keyLength * (2 + (isPrivateKey ? 1 : 0)))];

            // Write Key Header for ECCPrivateBlob or ECCPublicBlob.
            newBlob[0]  = (Byte)0x45;            // E
            newBlob[1]  = (Byte)0x43;            // C
            newBlob[2]  = (Byte)0x4B;            // K
            newBlob[3]  = (Byte)(keyLength == 32 ? 0x31 : (keyLength == 48 ? 0x33 : (keyLength == 64 ? 0x35 : 0x00)));
            newBlob[3] += (Byte)(isPrivateKey ? 0x01 : 0x00);
            newBlob[4]  = (Byte)keyLength;

            Array.Copy(keyCurveX, 0, newBlob, 8, keyCurveX.Length);
            Array.Copy(keyCurveY, 0, newBlob, 8 + keyLength, keyCurveY.Length);
            if (isPrivateKey)
            {
                Array.Copy(keyScalar, 0, newBlob, 8 + keyLength * 2, keyScalar.Length);
            }

            // Now return a valid Key.
            if (isPrivateKey)
            {
                return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPrivateBlob));
            }
            else
            {
                return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPublicBlob));
            }
        }