예제 #1
0
        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));
                }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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()));
                        }
                    }
                }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
        }
예제 #6
0
        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
            });
        }