Пример #1
0
        /// <summary>
        /// Create a new AsymCryptoSystem from TPM public parameter. This can then
        /// be used to validate TPM signatures or encrypt data destined for a TPM.
        /// </summary>
        /// <param name="pubKey"></param>
        /// <param name="privKey"></param>
        /// <returns></returns>
        public static AsymCryptoSystem CreateFrom(TpmPublic pubKey, TpmPrivate privKey = null)
        {
            var cs = new AsymCryptoSystem();

            TpmAlgId keyAlgId = pubKey.type;

            cs.PublicParms = pubKey.Copy();

            // Create an algorithm provider from the provided PubKey
            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
            {
                RawRsa rr     = null;
                byte[] prime1 = null,
                prime2 = null;
                if (privKey != null)
                {
                    rr     = new RawRsa(pubKey, privKey);
                    prime1 = RawRsa.ToBigEndian(rr.P);
                    prime2 = RawRsa.ToBigEndian(rr.Q);
                }
                var rsaParams = (RsaParms)pubKey.parameters;
                var exponent  = rsaParams.exponent != 0
                                            ? Globs.HostToNet(rsaParams.exponent)
                                            : RsaParms.DefaultExponent;
                var modulus = (pubKey.unique as Tpm2bPublicKeyRsa).buffer;
#if TSS_USE_BCRYPT
                var alg = new BCryptAlgorithm(Native.BCRYPT_RSA_ALGORITHM);
                cs.Key = alg.LoadRSAKey(exponent, modulus, prime1, prime2);
                alg.Close();
#else
                var dotNetPubParms = new RSAParameters()
                {
                    Exponent = exponent, Modulus = modulus
                };
                if (privKey != null)
                {
                    dotNetPubParms.P        = prime1;
                    dotNetPubParms.Q        = prime2;
                    dotNetPubParms.D        = RawRsa.ToBigEndian(rr.D);
                    dotNetPubParms.InverseQ = RawRsa.ToBigEndian(rr.InverseQ);
                    dotNetPubParms.DP       = RawRsa.ToBigEndian(rr.DP);
                    dotNetPubParms.DQ       = RawRsa.ToBigEndian(rr.DQ);
                }
                cs.RsaProvider = new RSACryptoServiceProvider();
                cs.RsaProvider.ImportParameters(dotNetPubParms);
#endif
                break;
            }

#if !__MonoCS__
            case TpmAlgId.Ecc:
            {
                var eccParms = (EccParms)pubKey.parameters;
                var eccPub   = (EccPoint)pubKey.unique;
                var algId    = RawEccKey.GetEccAlg(pubKey);
                if (algId == null)
                {
                    return(null);
                }
                bool   isEcdsa = eccParms.scheme.GetUnionSelector() == TpmAlgId.Ecdsa;
                byte[] keyBlob = RawEccKey.GetKeyBlob(eccPub.x, eccPub.y, keyAlgId,
                                                      !isEcdsa, eccParms.curveID);
#if TSS_USE_BCRYPT
                var alg = new BCryptAlgorithm(algId);
                cs.Key = alg.ImportKeyPair(Native.BCRYPT_ECCPUBLIC_BLOB, keyBlob);
                alg.Close();
                if (cs.Key == UIntPtr.Zero)
                {
                    Globs.Throw("Failed to create new RSA key");
                    return(null);
                }
#else
                CngKey eccKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob);

                if (pubKey.objectAttributes.HasFlag(ObjectAttr.Sign))
                {
                    cs.EcdsaProvider = new ECDsaCng(eccKey);
                }
                else
                {
                    cs.EcDhProvider = new ECDiffieHellmanCng(eccKey);
                }
#endif // !TSS_USE_BCRYPT
                break;
            }
#endif // !__MonoCS__
            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                cs = null;
                break;
            }
            return(cs);
        }
Пример #2
0
        /// <summary>
        /// Create a new AsymCryptoSystem from TPM public parameter. This can then
        /// be used to validate TPM signatures or encrypt data destined for a TPM.
        /// </summary>
        /// <param name="pubKey"></param>
        /// <returns></returns>
        public static AsymCryptoSystem CreateFrom(TpmPublic pubKey, TpmPrivate privKey = null)
        {
            var cs = new AsymCryptoSystem();

            TpmAlgId keyAlgId = pubKey.type;

            cs.PublicParms = pubKey.Copy();

            // Create an algorithm provider from the provided PubKey
            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
            {
                RawRsa rr     = null;
                byte[] prime1 = null,
                prime2 = null;
                if (privKey != null)
                {
                    rr     = new RawRsa(pubKey, privKey);
                    prime1 = RawRsa.ToBigEndian(rr.P);
                    prime2 = RawRsa.ToBigEndian(rr.Q);
                }
                var rsaParams = (RsaParms)pubKey.parameters;
                var exponent  = rsaParams.exponent != 0
                                                ? Globs.HostToNet(rsaParams.exponent)
                                                : RsaParms.DefaultExponent;
                var modulus = (pubKey.unique as Tpm2bPublicKeyRsa).buffer;
                AsymmetricKeyAlgorithmProvider rsaProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha256);

                uint primeLen1 = 0, primeLen2 = 0;
                // Compute the size of BCRYPT_RSAKEY_BLOB
                int rsaKeySize = exponent.Length + modulus.Length + 24;
                if (prime1 != null && prime1.Length > 0)
                {
                    if (prime2 == null || prime2.Length == 0)
                    {
                        Globs.Throw <ArgumentException>("LoadRSAKey(): The second prime is missing");
                        return(null);
                    }
                    primeLen1   = (uint)prime1.Length;
                    primeLen2   = (uint)prime2.Length;
                    rsaKeySize += prime1.Length + prime2.Length;
                }
                else if (prime2 != null && prime2.Length > 0)
                {
                    Globs.Throw <ArgumentException>("LoadRSAKey(): The first prime is missing");
                    return(null);
                }

                var rsaKey = new byte[rsaKeySize];

                // Initialize BCRYPT_RSAKEY_BLOB
                int offset = 0;
                WriteToBuffer(ref rsaKey, ref offset, primeLen1 == 0 ?
                              BCRYPT_RSAPUBLIC_MAGIC : BCRYPT_RSAPRIVATE_MAGIC);
                WriteToBuffer(ref rsaKey, ref offset, (uint)modulus.Length * 8);
                WriteToBuffer(ref rsaKey, ref offset, (uint)exponent.Length);
                WriteToBuffer(ref rsaKey, ref offset, (uint)modulus.Length);
                WriteToBuffer(ref rsaKey, ref offset, primeLen1);
                WriteToBuffer(ref rsaKey, ref offset, primeLen1);
                WriteToBuffer(ref rsaKey, ref offset, exponent);
                WriteToBuffer(ref rsaKey, ref offset, modulus);
                if (primeLen1 != 0)
                {
                    WriteToBuffer(ref rsaKey, ref offset, prime1);
                    WriteToBuffer(ref rsaKey, ref offset, prime2);
                }

                IBuffer rsaBuffer = CryptographicBuffer.CreateFromByteArray(rsaKey);

                if (primeLen1 == 0)
                {
                    cs.Key = rsaProvider.ImportPublicKey(rsaBuffer, CryptographicPublicKeyBlobType.BCryptPublicKey);
                }
                else
                {
                    cs.Key = rsaProvider.ImportKeyPair(rsaBuffer, CryptographicPrivateKeyBlobType.BCryptPrivateKey);
                }
                break;
            }

            case TpmAlgId.Ecc:
            {
                var eccParms = (EccParms)pubKey.parameters;
                var eccPub   = (EccPoint)pubKey.unique;
                var algId    = RawEccKey.GetEccAlg(pubKey);
                if (algId == null)
                {
                    return(null);
                }
                bool   isEcdsa = eccParms.scheme.GetUnionSelector() == TpmAlgId.Ecdsa;
                byte[] keyBlob = RawEccKey.GetKeyBlob(eccPub.x, eccPub.y, keyAlgId,
                                                      !isEcdsa, eccParms.curveID);
                AsymmetricKeyAlgorithmProvider eccProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algId);
                cs.Key = eccProvider.ImportKeyPair(CryptographicBuffer.CreateFromByteArray(keyBlob));
                break;
            }

            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                cs = null;
                break;
            }
            return(cs);
        }