internal static unsafe Pkcs8Response ImportEncryptedPkcs8PrivateKey( ReadOnlySpan <byte> passwordBytes, ReadOnlySpan <byte> source, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { // Since there's no bytes-based-password PKCS8 import in CNG, just do the decryption // here and call the unencrypted PKCS8 import. ArraySegment <byte> decrypted = KeyFormatHelper.DecryptPkcs8( passwordBytes, manager.Memory, out bytesRead); Span <byte> decryptedSpan = decrypted; try { return(ImportPkcs8(decryptedSpan)); } catch (CryptographicException e) { throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e); } finally { CryptographicOperations.ZeroMemory(decryptedSpan); CryptoPool.Return(decrypted.Array !); } } } }
internal static unsafe Pkcs8Response ImportEncryptedPkcs8PrivateKey( ReadOnlySpan <char> password, ReadOnlySpan <byte> source, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); int len = reader.ReadEncodedValue().Length; source = source.Slice(0, len); try { bytesRead = len; return(ImportPkcs8(source, password)); } catch (CryptographicException) { } ArraySegment <byte> decrypted = KeyFormatHelper.DecryptPkcs8( password, manager.Memory.Slice(0, len), out int innerRead); Span <byte> decryptedSpan = decrypted; try { if (innerRead != len) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } bytesRead = len; return(ImportPkcs8(decryptedSpan)); } catch (CryptographicException e) { throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e); } finally { CryptographicOperations.ZeroMemory(decryptedSpan); CryptoPool.Return(decrypted.Array !, clearSize: 0); } } } }
internal static unsafe Pkcs8Response ImportEncryptedPkcs8PrivateKey( ReadOnlySpan <char> password, ReadOnlySpan <byte> source, out int bytesRead) { try { AsnDecoder.ReadEncodedValue( source, AsnEncodingRules.BER, out _, out _, out int len); source = source.Slice(0, len); fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { try { bytesRead = len; return(ImportPkcs8(source, password)); } catch (CryptographicException) { } ArraySegment <byte> decrypted = KeyFormatHelper.DecryptPkcs8( password, manager.Memory.Slice(0, len), out int innerRead); Span <byte> decryptedSpan = decrypted; try { if (innerRead != len) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } bytesRead = len; return(ImportPkcs8(decryptedSpan)); } catch (CryptographicException e) { AsnWriter?pkcs8ZeroPublicKey = RewritePkcs8ECPrivateKeyWithZeroPublicKey(decryptedSpan); if (pkcs8ZeroPublicKey == null) { throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e); } try { bytesRead = len; return(ImportPkcs8(pkcs8ZeroPublicKey)); } catch (CryptographicException) { throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e); } } finally { CryptoPool.Return(decrypted); } } } } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } }