예제 #1
0
 internal RSASecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey)
 {
     SetKey(SecKeyPair.PublicPrivatePair(publicKey, privateKey));
 }
예제 #2
0
            public override void ImportParameters(DSAParameters parameters)
            {
                if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null)
                {
                    throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields);
                }

                // J is not required and is not even used on CNG blobs.
                // It should, however, be less than P (J == (P-1) / Q).
                // This validation check is just to maintain parity with DSACng and DSACryptoServiceProvider,
                // which also perform this check.
                if (parameters.J != null && parameters.J.Length >= parameters.P.Length)
                {
                    throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ);
                }

                int  keySize       = parameters.P.Length;
                bool hasPrivateKey = parameters.X != null;

                if (parameters.G.Length != keySize || parameters.Y.Length != keySize)
                {
                    throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY);
                }

                if (hasPrivateKey && parameters.X.Length != parameters.Q.Length)
                {
                    throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
                }

                if (!(8 * parameters.P.Length).IsLegalSize(LegalKeySizes))
                {
                    throw new CryptographicException(SR.Cryptography_InvalidKeySize);
                }

                if (parameters.Q.Length != 20)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey);
                }

                ThrowIfDisposed();

                if (hasPrivateKey)
                {
                    SafeSecKeyRefHandle privateKey = ImportKey(parameters);

                    DSAParameters publicOnly = parameters;
                    publicOnly.X = null;

                    SafeSecKeyRefHandle publicKey;
                    try
                    {
                        publicKey = ImportKey(publicOnly);
                    }
                    catch
                    {
                        privateKey.Dispose();
                        throw;
                    }

                    SetKey(SecKeyPair.PublicPrivatePair(publicKey, privateKey));
                }
                else
                {
                    SafeSecKeyRefHandle publicKey = ImportKey(parameters);
                    SetKey(SecKeyPair.PublicOnly(publicKey));
                }
            }
예제 #3
0
 internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey)
 {
     KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicPrivatePair(publicKey, privateKey));
 }
예제 #4
0
 internal RSASecurityTransforms(SafeSecKeyRefHandle publicKey)
 {
     SetKey(SecKeyPair.PublicOnly(publicKey));
 }
예제 #5
0
            public override RSAParameters ExportParameters(bool includePrivateParameters)
            {
                // Apple requires all private keys to be exported encrypted, but since we're trying to export
                // as parsed structures we will need to decrypt it for the user.
                const string ExportPassword = "******";
                SecKeyPair   keys           = GetKeys();

                if (keys.PublicKey == null ||
                    (includePrivateParameters && keys.PrivateKey == null))
                {
                    throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
                }

                byte[] keyBlob = Interop.AppleCrypto.SecKeyExport(
                    includePrivateParameters ? keys.PrivateKey : keys.PublicKey,
                    exportPrivate: includePrivateParameters,
                    password: ExportPassword);

                try
                {
                    if (!includePrivateParameters)
                    {
                        // When exporting a key handle opened from a certificate, it seems to
                        // export as a PKCS#1 blob instead of an X509 SubjectPublicKeyInfo blob.
                        // So, check for that.
                        // NOTE: It doesn't affect macOS Mojave when SecCertificateCopyKey API
                        // is used.
                        RSAParameters key;

                        AsnReader reader         = new AsnReader(keyBlob, AsnEncodingRules.BER);
                        AsnReader sequenceReader = reader.ReadSequence();

                        if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer))
                        {
                            AlgorithmIdentifierAsn ignored = default;
                            RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key);
                        }
                        else
                        {
                            RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(
                                keyBlob,
                                out int localRead,
                                out key);
                            Debug.Assert(localRead == keyBlob.Length);
                        }
                        return(key);
                    }
                    else
                    {
                        RSAKeyFormatHelper.ReadEncryptedPkcs8(
                            keyBlob,
                            ExportPassword,
                            out int localRead,
                            out RSAParameters key);
                        return(key);
                    }
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(keyBlob);
                }
            }
예제 #6
0
 internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey)
 {
     KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicOnly(publicKey));
 }
예제 #7
0
            public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten)
            {
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                RsaPaddingProcessor processor = null;

                if (padding.Mode == RSASignaturePaddingMode.Pss)
                {
                    processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
                }
                else if (padding != RSASignaturePadding.Pkcs1)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
                }

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                int keySize = KeySize;
                int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                if (processor == null)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    if (destination.Length < rsaSize)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    return(Interop.AppleCrypto.TryGenerateSignature(
                               keys.PrivateKey,
                               hash,
                               destination,
                               palAlgId,
                               out bytesWritten));
                }

                Debug.Assert(padding.Mode == RSASignaturePaddingMode.Pss);

                if (destination.Length < rsaSize)
                {
                    bytesWritten = 0;
                    return(false);
                }

                byte[] rented = ArrayPool <byte> .Shared.Rent(rsaSize);

                Span <byte> buf = new Span <byte>(rented, 0, rsaSize);

                processor.EncodePss(hash, buf, keySize);

                try
                {
                    return(Interop.AppleCrypto.TryRsaSignaturePrimitive(keys.PrivateKey, buf, destination, out bytesWritten));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(buf);
                    ArrayPool <byte> .Shared.Return(rented);
                }
            }
예제 #8
0
            public override RSAParameters ExportParameters(bool includePrivateParameters)
            {
                SecKeyPair keys = GetKeys();

                if (includePrivateParameters && keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
                }

                bool gotKeyBlob = Interop.AppleCrypto.TrySecKeyCopyExternalRepresentation(
                    includePrivateParameters ? keys.PrivateKey ! : keys.PublicKey,
                    out byte[] keyBlob);

                if (!gotKeyBlob)
                {
                    return(ExportParametersFromLegacyKey(keys, includePrivateParameters));
                }

                try
                {
                    if (!includePrivateParameters)
                    {
                        // When exporting a key handle opened from a certificate, it seems to
                        // export as a PKCS#1 blob instead of an X509 SubjectPublicKeyInfo blob.
                        // So, check for that.
                        // NOTE: It doesn't affect macOS Mojave when SecCertificateCopyKey API
                        // is used.
                        RSAParameters key;

                        AsnReader reader         = new AsnReader(keyBlob, AsnEncodingRules.BER);
                        AsnReader sequenceReader = reader.ReadSequence();

                        if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer))
                        {
                            AlgorithmIdentifierAsn ignored = default;
                            RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key);
                        }
                        else
                        {
                            RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(
                                keyBlob,
                                out int localRead,
                                out key);
                            Debug.Assert(localRead == keyBlob.Length);
                        }
                        return(key);
                    }
                    else
                    {
                        AlgorithmIdentifierAsn ignored = default;
                        RSAKeyFormatHelper.FromPkcs1PrivateKey(
                            keyBlob,
                            ignored,
                            out RSAParameters key);
                        return(key);
                    }
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(keyBlob);
                }
            }
예제 #9
0
            public override bool TrySignHash(ReadOnlySpan <byte> hash, Span <byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten)
            {
                ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm));
                ArgumentNullException.ThrowIfNull(padding);

                ThrowIfDisposed();

                bool pssPadding = padding.Mode switch
                {
                    RSASignaturePaddingMode.Pss => true,
                    RSASignaturePaddingMode.Pkcs1 => false,
                    _ => throw new CryptographicException(SR.Cryptography_InvalidPaddingMode)
                };

                SecKeyPair keys = GetKeys();

                if (keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                }

                int keySize = KeySize;
                int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(keySize);

                if (!pssPadding)
                {
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out int expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    if (destination.Length < rsaSize)
                    {
                        bytesWritten = 0;
                        return(false);
                    }

                    return(Interop.AppleCrypto.TryCreateSignature(
                               keys.PrivateKey,
                               hash,
                               destination,
                               palAlgId,
                               Interop.AppleCrypto.PAL_SignatureAlgorithm.RsaPkcs1,
                               out bytesWritten));
                }

                Debug.Assert(padding.Mode == RSASignaturePaddingMode.Pss);

                if (destination.Length < rsaSize)
                {
                    bytesWritten = 0;
                    return(false);
                }

                byte[]      rented = CryptoPool.Rent(rsaSize);
                Span <byte> buf    = new Span <byte>(rented, 0, rsaSize);

                RsaPaddingProcessor.EncodePss(hashAlgorithm, hash, buf, keySize);

                try
                {
                    return(Interop.AppleCrypto.TryRsaSignaturePrimitive(keys.PrivateKey, buf, destination, out bytesWritten));
                }
                finally
                {
                    CryptographicOperations.ZeroMemory(buf);
                    CryptoPool.Return(rented, clearSize: 0);
                }
            }
예제 #10
0
            public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
            {
                if (hash == null)
                {
                    throw new ArgumentNullException(nameof(hash));
                }
                if (string.IsNullOrEmpty(hashAlgorithm.Name))
                {
                    throw HashAlgorithmNameNullOrEmpty();
                }
                if (padding == null)
                {
                    throw new ArgumentNullException(nameof(padding));
                }

                ThrowIfDisposed();

                if (padding == RSASignaturePadding.Pkcs1)
                {
                    SecKeyPair keys = GetKeys();

                    if (keys.PrivateKey == null)
                    {
                        throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
                    }

                    int expectedSize;
                    Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
                        PalAlgorithmFromAlgorithmName(hashAlgorithm, out expectedSize);

                    if (hash.Length != expectedSize)
                    {
                        // Windows: NTE_BAD_DATA ("Bad Data.")
                        // OpenSSL: RSA_R_INVALID_MESSAGE_LENGTH ("invalid message length")
                        throw new CryptographicException(
                                  SR.Format(
                                      SR.Cryptography_BadHashSize_ForAlgorithm,
                                      hash.Length,
                                      expectedSize,
                                      hashAlgorithm.Name));
                    }

                    return(Interop.AppleCrypto.GenerateSignature(
                               keys.PrivateKey,
                               hash,
                               palAlgId));
                }

                // A signature will always be the keysize (in ceiling-bytes) in length.
                int outputSize = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);

                byte[] output = new byte[outputSize];

                if (!TrySignHash(hash, output, hashAlgorithm, padding, out int bytesWritten))
                {
                    Debug.Fail("TrySignHash failed with a pre-allocated buffer");
                    throw new CryptographicException();
                }

                Debug.Assert(bytesWritten == outputSize);
                return(output);
            }
예제 #11
0
 public void Dispose()
 {
     _keys?.Dispose();
     _keys = null;
 }