private static SafeSecKeyRefHandle ImportKey(RSAParameters parameters) { AsnWriter keyWriter; bool hasPrivateKey; if (parameters.D != null) { keyWriter = RSAKeyFormatHelper.WritePkcs1PrivateKey(parameters); hasPrivateKey = true; } else { keyWriter = RSAKeyFormatHelper.WriteSubjectPublicKeyInfo(parameters); hasPrivateKey = false; } byte[] rented = CryptoPool.Rent(keyWriter.GetEncodedLength()); if (!keyWriter.TryEncode(rented, out int written)) { Debug.Fail("TryEncode failed with a pre-allocated buffer"); throw new InvalidOperationException(); } // Explicitly clear the inner buffer keyWriter.Reset(); try { return(Interop.AppleCrypto.ImportEphemeralKey(rented.AsSpan(0, written), hasPrivateKey)); } finally { CryptoPool.Return(rented, written); } }
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 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 (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); } }
private AsnWriter WritePkcs1PublicKey() { RSAParameters rsaParameters = ExportParameters(false); return(RSAKeyFormatHelper.WritePkcs1PublicKey(rsaParameters)); }