private byte[] EncryptContent( ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, out byte[] cek, out byte[] parameterBytes) { using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) using (ICryptoTransform encryptor = alg.CreateEncryptor()) { cek = alg.Key; if (alg is RC2) { Rc2CbcParameters rc2Params = new Rc2CbcParameters(alg.IV, alg.KeySize); using (AsnWriter writer = AsnSerializer.Serialize(rc2Params, AsnEncodingRules.DER)) { parameterBytes = writer.Encode(); } } else { parameterBytes = EncodeOctetString(alg.IV); } byte[] toEncrypt = contentInfo.Content; if (contentInfo.ContentType.Value == Oids.Pkcs7Data) { toEncrypt = EncodeOctetString(toEncrypt); } return(encryptor.OneShot(toEncrypt)); } }
private static SymmetricAlgorithm OpenAlgorithm(AlgorithmIdentifierAsn contentEncryptionAlgorithm) { SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm.Algorithm); if (alg is RC2) { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Rc2CbcParameters rc2Params = Rc2CbcParameters.Decode( contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); alg.KeySize = rc2Params.GetEffectiveKeyBits(); alg.IV = rc2Params.Iv.ToArray(); } else { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } AsnReader reader = new AsnReader(contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); if (reader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> primitiveBytes)) { alg.IV = primitiveBytes.ToArray(); } else { byte[] iv = new byte[alg.BlockSize / 8]; if (!reader.TryCopyOctetStringBytes(iv, out int bytesWritten) || bytesWritten != iv.Length) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } alg.IV = iv; } } return(alg); }
private byte[] EncryptContent( ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, out byte[] cek, out byte[] parameterBytes) { using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) using (ICryptoTransform encryptor = alg.CreateEncryptor()) { cek = alg.Key; if (alg is RC2) { Rc2CbcParameters rc2Params = new Rc2CbcParameters(alg.IV, alg.KeySize); using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { rc2Params.Encode(writer); parameterBytes = writer.Encode(); } } else { parameterBytes = EncodeOctetString(alg.IV); } byte[] toEncrypt = contentInfo.Content; if (contentInfo.ContentType.Value == Oids.Pkcs7Data) { toEncrypt = EncodeOctetString(toEncrypt); return(encryptor.OneShot(toEncrypt)); } else { if (contentInfo.Content.Length == 0) { return(encryptor.OneShot(contentInfo.Content)); } else { AsnReader reader = new AsnReader(contentInfo.Content, AsnEncodingRules.BER); return(encryptor.OneShot(reader.PeekContentBytes().ToArray())); } } } }
private static SymmetricAlgorithm OpenAlgorithm(AlgorithmIdentifierAsn contentEncryptionAlgorithm) { SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm.Algorithm); if (alg is RC2) { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Rc2CbcParameters rc2Params = Rc2CbcParameters.Decode( contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); alg.KeySize = rc2Params.GetEffectiveKeyBits(); alg.IV = rc2Params.Iv.ToArray(); } else { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } try { AsnReader reader = new AsnReader(contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); alg.IV = reader.ReadOctetString(); if (alg.IV.Length != alg.BlockSize / 8) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } return(alg); }
internal static AlgorithmIdentifier ToPresentationObject(this AlgorithmIdentifierAsn asn) { int keyLength; switch (asn.Algorithm.Value) { case Oids.Rc2Cbc: { if (asn.Parameters == null) { keyLength = 0; break; } Rc2CbcParameters rc2Params = AsnSerializer.Deserialize <Rc2CbcParameters>( asn.Parameters.Value, AsnEncodingRules.BER); int keySize = rc2Params.GetEffectiveKeyBits(); // These are the only values .NET Framework would set. switch (keySize) { case 40: case 56: case 64: case 128: keyLength = keySize; break; default: keyLength = 0; break; } break; } case Oids.Rc4: { if (asn.Parameters == null) { keyLength = 0; break; } int saltLen = 0; AsnReader reader = new AsnReader(asn.Parameters.Value, AsnEncodingRules.BER); // DER NULL is considered the same as not present. // No call to ReadNull() is necessary because the serializer already verified that // there's no data after the [AnyValue] value. if (reader.PeekTag() != Asn1Tag.Null) { if (reader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> contents)) { saltLen = contents.Length; } else { Span <byte> salt = stackalloc byte[KeyLengths.Rc4Max_128Bit / 8]; if (!reader.TryCopyOctetStringBytes(salt, out saltLen)) { throw new CryptographicException(); } } } keyLength = KeyLengths.Rc4Max_128Bit - 8 * saltLen; break; } case Oids.DesCbc: keyLength = KeyLengths.Des_64Bit; break; case Oids.TripleDesCbc: keyLength = KeyLengths.TripleDes_192Bit; break; default: // .NET Framework doesn't set a keylength for AES, or any other algorithm than the ones // listed here. keyLength = 0; break; } return(new AlgorithmIdentifier(new Oid(asn.Algorithm), keyLength)); }
internal static AlgorithmIdentifier ToPresentationObject(this AlgorithmIdentifierAsn asn) { int keyLength; byte[] parameters = Array.Empty <byte>(); switch (asn.Algorithm) { case Oids.Rc2Cbc: { if (asn.Parameters == null) { keyLength = 0; break; } Rc2CbcParameters rc2Params = Rc2CbcParameters.Decode( asn.Parameters.Value, AsnEncodingRules.BER); int keySize = rc2Params.GetEffectiveKeyBits(); // These are the only values .NET Framework would set. switch (keySize) { case 40: case 56: case 64: case 128: keyLength = keySize; break; default: keyLength = 0; break; } break; } case Oids.Rc4: { if (asn.Parameters == null) { keyLength = 0; break; } int saltLen = 0; try { AsnReader reader = new AsnReader(asn.Parameters.Value, AsnEncodingRules.BER); // DER NULL is considered the same as not present. // No call to ReadNull() is necessary because the serializer already verified that // there's no data after the [AnyValue] value. if (reader.PeekTag() != Asn1Tag.Null) { if (reader.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> contents)) { saltLen = contents.Length; } else { Span <byte> salt = stackalloc byte[KeyLengths.Rc4Max_128Bit / 8]; if (!reader.TryReadOctetString(salt, out saltLen)) { throw new CryptographicException(); } } } } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } keyLength = KeyLengths.Rc4Max_128Bit - 8 * saltLen; break; } case Oids.DesCbc: keyLength = KeyLengths.Des_64Bit; break; case Oids.TripleDesCbc: keyLength = KeyLengths.TripleDes_192Bit; break; case Oids.RsaOaep when !asn.HasNullEquivalentParameters(): keyLength = 0; Debug.Assert(asn.Parameters != null); parameters = asn.Parameters.Value.ToArray(); break; default: // .NET Framework doesn't set a keylength for AES, or any other algorithm than the ones // listed here. keyLength = 0; break; } return(new AlgorithmIdentifier(new Oid(asn.Algorithm), keyLength) { Parameters = parameters }); }