internal RSASecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey) { SetKey(SecKeyPair.PublicPrivatePair(publicKey, privateKey)); }
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)); } }
internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey) { KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicPrivatePair(publicKey, privateKey)); }
internal RSASecurityTransforms(SafeSecKeyRefHandle publicKey) { SetKey(SecKeyPair.PublicOnly(publicKey)); }
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); } }
internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey) { KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicOnly(publicKey)); }
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); } }
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); } }
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); } }
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); }
public void Dispose() { _keys?.Dispose(); _keys = null; }