Esempio n. 1
0
        internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan <byte> key, out int bytesRead)
        {
            try
            {
                AsnDecoder.ReadEncodedValue(
                    key,
                    AsnEncodingRules.BER,
                    out _,
                    out _,
                    out int firstValueLength);

                fixed(byte *ptr = &MemoryMarshal.GetReference(key))
                {
                    using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, firstValueLength))
                    {
                        AlgorithmIdentifierAsn algId = default;
                        FromECPrivateKey(manager.Memory, algId, out ECParameters ret);
                        bytesRead = firstValueLength;
                        return(ret);
                    }
                }
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Esempio n. 2
0
        public virtual unsafe void ImportRSAPrivateKey(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);
                    ReadOnlyMemory <byte> firstValue = reader.PeekEncodedValue();
                    int localRead = firstValue.Length;

                    AlgorithmIdentifierAsn ignored = default;
                    RSAKeyFormatHelper.FromPkcs1PrivateKey(firstValue, ignored, out RSAParameters rsaParameters);

                    fixed(byte *dPin = rsaParameters.D)
                    fixed(byte *pPin    = rsaParameters.P)
                    fixed(byte *qPin    = rsaParameters.Q)
                    fixed(byte *dpPin   = rsaParameters.DP)
                    fixed(byte *dqPin   = rsaParameters.DQ)
                    fixed(byte *qInvPin = rsaParameters.InverseQ)
                    {
                        try
                        {
                            ImportParameters(rsaParameters);
                        }
                        finally
                        {
                            ClearPrivateParameters(rsaParameters);
                        }
                    }

                    bytesRead = localRead;
                }
            }
        }
Esempio n. 3
0
            public static unsafe ContentInfo?TryDecryptCore(
                byte[] cek,
                string contentType,
                ReadOnlyMemory <byte>?content,
                AlgorithmIdentifierAsn contentEncryptionAlgorithm,
                out Exception?exception)
            {
                if (content == null)
                {
                    exception = null;

                    return(new ContentInfo(
                               new Oid(contentType),
                               Array.Empty <byte>()));
                }

                byte[]? decrypted = DecryptContent(content.Value, cek, contentEncryptionAlgorithm, out exception);

                if (exception != null)
                {
                    return(null);
                }

                if (contentType != Oids.Pkcs7Data)
                {
                    decrypted = GetAsnSequenceWithContentNoValidation(decrypted);
                }

                exception = null;
                return(new ContentInfo(
                           new Oid(contentType),
                           decrypted !));
            }
Esempio n. 4
0
        public virtual unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead)
        {
            try
            {
                AsnDecoder.ReadEncodedValue(
                    source,
                    AsnEncodingRules.BER,
                    out _,
                    out _,
                    out int localRead);

                fixed(byte *ptr = &MemoryMarshal.GetReference(source))
                {
                    using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, localRead))
                    {
                        AlgorithmIdentifierAsn ignored = default;
                        RSAKeyFormatHelper.ReadRsaPublicKey(manager.Memory, ignored, out RSAParameters rsaParameters);

                        ImportParameters(rsaParameters);

                        bytesRead = localRead;
                    }
                }
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Esempio n. 5
0
        private static unsafe AsnWriter?RewritePkcs8ECPrivateKeyWithZeroPublicKey(ReadOnlySpan <byte> source)
        {
            fixed(byte *ptr = &MemoryMarshal.GetReference(source))
            {
                using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                {
                    PrivateKeyInfoAsn      privateKeyInfo   = PrivateKeyInfoAsn.Decode(manager.Memory, AsnEncodingRules.BER);
                    AlgorithmIdentifierAsn privateAlgorithm = privateKeyInfo.PrivateKeyAlgorithm;

                    if (privateAlgorithm.Algorithm.Value != Oids.EcPublicKey)
                    {
                        return(null);
                    }

                    ECPrivateKey privateKey = ECPrivateKey.Decode(privateKeyInfo.PrivateKey, AsnEncodingRules.BER);
                    EccKeyFormatHelper.FromECPrivateKey(privateKey, privateAlgorithm, out ECParameters ecParameters);

                    fixed(byte *pD = ecParameters.D)
                    {
                        try
                        {
                            if (!ecParameters.Curve.IsExplicit || ecParameters.Q.X != null || ecParameters.Q.Y != null)
                            {
                                return(null);
                            }

                            byte[] zero = new byte[ecParameters.D !.Length];
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out KeyTransRecipientInfoAsn decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            ReadOnlySpan <byte> rebindSpan     = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


            if (!sequenceReader.TryReadInt32(out decoded.Version))
            {
                sequenceReader.ThrowIfNotEmpty();
            }

            RecipientIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.Rid);
            AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.KeyEncryptionAlgorithm);

            if (sequenceReader.TryReadPrimitiveOctetStringBytes(out tmpSpan))
            {
                decoded.EncryptedKey = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            }
            else
            {
                decoded.EncryptedKey = sequenceReader.ReadOctetString();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 7
0
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out SignerInfoAsn decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


            if (!sequenceReader.TryReadInt32(out decoded.Version))
            {
                sequenceReader.ThrowIfNotEmpty();
            }

            SignerIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.Sid);
            AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.DigestAlgorithm);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                tmpSpan = sequenceReader.ReadEncodedValue();
                decoded.SignedAttributes    = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
                decoded.SignedAttributesSet = SignedAttributesSet.Decode(decoded.SignedAttributes.Value, AsnEncodingRules.BER);
            }

            AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.SignatureAlgorithm);

            if (sequenceReader.TryReadPrimitiveOctetStringBytes(out tmpSpan))
            {
                decoded.SignatureValue = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            }
            else
            {
                decoded.SignatureValue = sequenceReader.ReadOctetString();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for UnsignedAttributes
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var          tmpList = new List <AttributeAsn>();
                    AttributeAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        AttributeAsn.Decode(ref collectionReader, rebind, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.UnsignedAttributes = tmpList.ToArray();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 8
0
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out KeyAgreeRecipientInfoAsn decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      explicitReader;
            AsnValueReader      collectionReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


            if (!sequenceReader.TryReadInt32(out decoded.Version))
            {
                sequenceReader.ThrowIfNotEmpty();
            }


            explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            OriginatorIdentifierOrKeyAsn.Decode(ref explicitReader, rebind, out decoded.Originator);
            explicitReader.ThrowIfNotEmpty();


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));

                if (explicitReader.TryReadPrimitiveOctetStringBytes(out tmpSpan))
                {
                    decoded.Ukm = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
                }
                else
                {
                    decoded.Ukm = explicitReader.ReadOctetString();
                }

                explicitReader.ThrowIfNotEmpty();
            }

            AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.KeyEncryptionAlgorithm);

            // Decode SEQUENCE OF for RecipientEncryptedKeys
            {
                collectionReader = sequenceReader.ReadSequence();
                var tmpList = new List <RecipientEncryptedKeyAsn>();
                RecipientEncryptedKeyAsn tmpItem;

                while (collectionReader.HasData)
                {
                    RecipientEncryptedKeyAsn.Decode(ref collectionReader, rebind, out tmpItem);
                    tmpList.Add(tmpItem);
                }

                decoded.RecipientEncryptedKeys = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
 private DecryptorPalWindows(
     SafeCryptMsgHandle hCryptMsg,
     RecipientInfoCollection recipientInfos,
     AlgorithmIdentifierAsn contentEncryptionAlgorithm)
     : base(recipientInfos)
 {
     _hCryptMsg = hCryptMsg;
     _contentEncryptionAlgorithm = contentEncryptionAlgorithm;
 }
Esempio n. 10
0
        internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            // State validation should be runtime checks if/when this becomes public API
            Debug.Assert(signatureGenerator != null);
            Debug.Assert(Subject != null);
            Debug.Assert(PublicKey != null);

            byte[] signatureAlgorithm = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm);
            AlgorithmIdentifierAsn signatureAlgorithmAsn;

            // Deserialization also does validation of the value (except for Parameters, which have to be validated separately).
            signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER);
            if (signatureAlgorithmAsn.Parameters.HasValue)
            {
                Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value.Span);
            }

            SubjectPublicKeyInfoAsn spki = default;

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = PublicKey.Oid !.Value !, Parameters = PublicKey.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = PublicKey.EncodedKeyValue.RawData;

            var attributes = new AttributeAsn[Attributes.Count];

            for (int i = 0; i < attributes.Length; i++)
            {
                attributes[i] = new AttributeAsn(Attributes[i]);
            }

            CertificationRequestInfoAsn requestInfo = new CertificationRequestInfoAsn
            {
                Version = 0,
                Subject = this.Subject.RawData,
                SubjectPublicKeyInfo = spki,
                Attributes           = attributes
            };

            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            requestInfo.Encode(writer);
            byte[] encodedRequestInfo = writer.Encode();
            writer.Reset();

            CertificationRequestAsn certificationRequest = new CertificationRequestAsn
            {
                CertificationRequestInfo = requestInfo,
                SignatureAlgorithm       = signatureAlgorithmAsn,
                SignatureValue           = signatureGenerator.SignData(encodedRequestInfo, hashAlgorithm),
            };

            certificationRequest.Encode(writer);
            return(writer.Encode());
        }
    }
            public override RSAParameters ExportParameters(bool includePrivateParameters)
            {
                SecKeyPair keys = GetKeys();

                if (includePrivateParameters && keys.PrivateKey == null)
                {
                    throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
                }

                byte[] keyBlob = Interop.AppleCrypto.SecKeyCopyExternalRepresentation(
                    includePrivateParameters ? keys.PrivateKey ! : keys.PublicKey);

                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);
                }
            }
Esempio n. 12
0
        static EssCertIdV2()
        {
            EssCertIdV2           decoded = default;
            ReadOnlyMemory <byte> rebind  = default;
            AsnValueReader        reader;

            reader = new AsnValueReader(DefaultHashAlgorithm, AsnEncodingRules.DER);
            AlgorithmIdentifierAsn.Decode(ref reader, rebind, out decoded.HashAlgorithm);
            reader.ThrowIfNotEmpty();
        }
            private static RSAParameters ExportParametersFromLegacyKey(SecKeyPair keys, 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 = "******";

                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);
                }
            }
Esempio n. 14
0
        public static void SerializeNullAlgorithmIdentifier()
        {
            AlgorithmIdentifierAsn identifier = new AlgorithmIdentifierAsn
            {
                Algorithm  = new Oid(null, "SHA-2-256"),
                Parameters = new byte[] { 5, 0 },
            };

            Assert.Throws <CryptographicException>(
                () => AsnSerializer.Serialize(identifier, AsnEncodingRules.DER));
        }
Esempio n. 15
0
            private static byte[]? DecryptContent(
                ReadOnlyMemory <byte> encryptedContent,
                byte[] cek,
                AlgorithmIdentifierAsn contentEncryptionAlgorithm,
                out Exception?exception)
            {
                exception = null;
                int encryptedContentLength = encryptedContent.Length;

                byte[]? encryptedContentArray = CryptoPool.Rent(encryptedContentLength);

                try
                {
                    encryptedContent.CopyTo(encryptedContentArray);

                    using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm))
                    {
                        ICryptoTransform decryptor;

                        try
                        {
                            decryptor = alg.CreateDecryptor(cek, alg.IV);
                        }
                        catch (ArgumentException ae)
                        {
                            // Decrypting or deriving the symmetric key with the wrong key may still succeed
                            // but produce a symmetric key that is not the correct length.
                            throw new CryptographicException(SR.Cryptography_Cms_InvalidSymmetricKey, ae);
                        }

                        using (decryptor)
                        {
                            // If we extend this library to accept additional algorithm providers
                            // then a different array pool needs to be used.
                            Debug.Assert(alg.GetType().Assembly == typeof(Aes).Assembly);

                            return(decryptor.OneShot(
                                       encryptedContentArray,
                                       0,
                                       encryptedContentLength));
                        }
                    }
                }
                catch (CryptographicException e)
                {
                    exception = e;
                    return(null);
                }
                finally
                {
                    CryptoPool.Return(encryptedContentArray, encryptedContentLength);
                    encryptedContentArray = null;
                }
            }
Esempio n. 16
0
        private void ConsiderDigestAddition(AlgorithmIdentifierAsn candidate)
        {
            int curLength = _signedData.DigestAlgorithms.Length;

            for (int i = 0; i < curLength; i++)
            {
                ref AlgorithmIdentifierAsn alg = ref _signedData.DigestAlgorithms[i];

                if (candidate.Equals(ref alg))
                {
                    return;
                }
            }
Esempio n. 17
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);
        }
Esempio n. 18
0
            public static unsafe ContentInfo?TryDecryptCore(
                byte[] cek,
                string contentType,
                ReadOnlyMemory <byte>?content,
                AlgorithmIdentifierAsn contentEncryptionAlgorithm,
                out Exception?exception)
            {
                if (content == null)
                {
                    exception = null;

                    return(new ContentInfo(
                               new Oid(contentType),
                               Array.Empty <byte>()));
                }

                byte[]? decrypted = DecryptContent(content.Value, cek, contentEncryptionAlgorithm, out exception);

                if (exception != null)
                {
                    return(null);
                }

                // Compat: Previous versions of the managed PAL encryptor would wrap the contents in an octet stream
                // which is not correct and is incompatible with other CMS readers. To maintain compatibility with
                // existing CMS that have the incorrect wrapping, we attempt to remove it.
                if (contentType == Oids.Pkcs7Data)
                {
                    if (decrypted?.Length > 0 && decrypted[0] == 0x04)
                    {
                        try
                        {
                            decrypted = AsnDecoder.ReadOctetString(decrypted, AsnEncodingRules.BER, out _);
                        }
                        catch (AsnContentException)
                        {
                        }
                    }
                }
                else
                {
                    decrypted = GetAsnSequenceWithContentNoValidation(decrypted);
                }

                exception = null;
                return(new ContentInfo(
                           new Oid(contentType),
                           decrypted !));
            }
Esempio n. 19
0
        internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            // State validation should be runtime checks if/when this becomes public API
            Debug.Assert(signatureGenerator != null);
            Debug.Assert(Subject != null);
            Debug.Assert(PublicKey != null);

            byte[] signatureAlgorithm = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm);
            AlgorithmIdentifierAsn signatureAlgorithmAsn;

            // Deserialization also does validation of the value (except for Parameters, which have to be validated separately).
            signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER);
            if (signatureAlgorithmAsn.Parameters.HasValue)
            {
                Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value);
            }

            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn();

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = PublicKey.Oid, Parameters = PublicKey.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = PublicKey.EncodedKeyValue.RawData;

            CertificationRequestInfoAsn requestInfo = new CertificationRequestInfoAsn
            {
                Version = 0,
                Subject = this.Subject.RawData,
                SubjectPublicKeyInfo = spki,
                Attributes           = Attributes.Select(a => new AttributeAsn(a)).ToArray(),
            };

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                using (AsnWriter signedWriter = new AsnWriter(AsnEncodingRules.DER))
                {
                    requestInfo.Encode(writer);

                    byte[] encodedRequestInfo = writer.Encode();
                    CertificationRequestAsn certificationRequest = new CertificationRequestAsn
                    {
                        CertificationRequestInfo = requestInfo,
                        SignatureAlgorithm       = signatureAlgorithmAsn,
                        SignatureValue           = signatureGenerator.SignData(encodedRequestInfo, hashAlgorithm),
                    };

                    certificationRequest.Encode(signedWriter);
                    return(signedWriter.Encode());
                }
        }
        /// <summary>
        /// Sign the current certificate request to create a chain-signed or self-signed certificate.
        /// </summary>
        /// <param name="issuerName">The X500DistinguishedName for the Issuer</param>
        /// <param name="generator">
        ///   An <see cref="X509SignatureGenerator"/> representing the issuing certificate authority.
        /// </param>
        /// <param name="notBefore">
        ///   The oldest date and time where this certificate is considered valid.
        ///   Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds.
        /// </param>
        /// <param name="notAfter">
        ///   The date and time where this certificate is no longer considered valid.
        /// </param>
        /// <param name="serialNumber">
        ///   The serial number to use for the new certificate. This value should be unique per issuer.
        ///   The value is interpreted as an unsigned (big) integer in big endian byte ordering.
        /// </param>
        /// <returns>
        ///   An <see cref="X509Certificate2"/> with the specified values. The returned object will
        ///   not assert <see cref="X509Certificate2.HasPrivateKey" />.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="issuerName"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="generator"/> is null.</exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="notAfter"/> represents a date and time before <paramref name="notBefore"/>.
        /// </exception>
        /// <exception cref="ArgumentException"><paramref name="serialNumber"/> has length 0.</exception>
        /// <exception cref="CryptographicException">Any error occurs during the signing operation.</exception>
        public X509Certificate2 Create(
            X500DistinguishedName issuerName,
            X509SignatureGenerator generator,
            DateTimeOffset notBefore,
            DateTimeOffset notAfter,
            ReadOnlySpan <byte> serialNumber)
        {
            if (issuerName == null)
            {
                throw new ArgumentNullException(nameof(issuerName));
            }
            if (generator == null)
            {
                throw new ArgumentNullException(nameof(generator));
            }
            if (notAfter < notBefore)
            {
                throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed);
            }
            if (serialNumber == null || serialNumber.Length < 1)
            {
                throw new ArgumentException(SR.Arg_EmptyOrNullArray, nameof(serialNumber));
            }

            byte[] signatureAlgorithm = generator.GetSignatureAlgorithmIdentifier(HashAlgorithm);
            AlgorithmIdentifierAsn signatureAlgorithmAsn;

            // Deserialization also does validation of the value (except for Parameters, which have to be validated separately).
            signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER);
            if (signatureAlgorithmAsn.Parameters.HasValue)
            {
                Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value);
            }

            ArraySegment <byte> normalizedSerial = NormalizeSerialNumber(serialNumber);

            TbsCertificateAsn tbsCertificate = new TbsCertificateAsn
            {
                Version              = 2,
                SerialNumber         = normalizedSerial,
                SignatureAlgorithm   = signatureAlgorithmAsn,
                Issuer               = issuerName.RawData,
                SubjectPublicKeyInfo = new SubjectPublicKeyInfoAsn
                {
                    Algorithm = new AlgorithmIdentifierAsn
                    {
                        Algorithm  = PublicKey.Oid !.Value !,
                        Parameters = PublicKey.EncodedParameters.RawData,
                    },
Esempio n. 21
0
 internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan <byte> key, out int bytesRead)
 {
     fixed(byte *ptr = &MemoryMarshal.GetReference(key))
     {
         using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, key.Length))
         {
             AsnReader reader                  = new AsnReader(manager.Memory, AsnEncodingRules.BER);
             AlgorithmIdentifierAsn algId      = default;
             ReadOnlyMemory <byte>  firstValue = reader.PeekEncodedValue();
             FromECPrivateKey(firstValue, algId, out ECParameters ret);
             bytesRead = firstValue.Length;
             return(ret);
         }
     }
 }
Esempio n. 22
0
        internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan <byte> key, out int bytesRead)
        {
            fixed(byte *ptr = &MemoryMarshal.GetReference(key))
            {
                using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, key.Length))
                {
                    ECPrivateKey parsedKey =
                        AsnSerializer.Deserialize <ECPrivateKey>(manager.Memory, AsnEncodingRules.BER, out bytesRead);

                    ECParameters           ret;
                    AlgorithmIdentifierAsn algId = default;
                    FromECPrivateKey(parsedKey, algId, out ret);
                    return(ret);
                }
            }
        }
Esempio n. 23
0
        public virtual unsafe void ImportRSAPrivateKey(ReadOnlySpan <byte> source, out int bytesRead)
        {
            try
            {
                AsnDecoder.ReadEncodedValue(
                    source,
                    AsnEncodingRules.BER,
                    out _,
                    out _,
                    out int firstValueLength);

                fixed(byte *ptr = &MemoryMarshal.GetReference(source))
                {
                    using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, firstValueLength))
                    {
                        ReadOnlyMemory <byte> firstValue = manager.Memory;
                        int localRead = firstValue.Length;

                        AlgorithmIdentifierAsn ignored = default;
                        RSAKeyFormatHelper.FromPkcs1PrivateKey(firstValue, ignored, out RSAParameters rsaParameters);

                        fixed(byte *dPin = rsaParameters.D)
                        fixed(byte *pPin    = rsaParameters.P)
                        fixed(byte *qPin    = rsaParameters.Q)
                        fixed(byte *dpPin   = rsaParameters.DP)
                        fixed(byte *dqPin   = rsaParameters.DQ)
                        fixed(byte *qInvPin = rsaParameters.InverseQ)
                        {
                            try
                            {
                                ImportParameters(rsaParameters);
                            }
                            finally
                            {
                                ClearPrivateParameters(rsaParameters);
                            }
                        }

                        bytesRead = localRead;
                    }
                }
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Esempio n. 24
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);
        }
Esempio n. 25
0
        public static void SerializeAlgorithmIdentifier()
        {
            AlgorithmIdentifierAsn identifier = new AlgorithmIdentifierAsn
            {
                Algorithm  = new Oid("2.16.840.1.101.3.4.2.1", "SHA-2-256"),
                Parameters = new byte[] { 5, 0 },
            };

            using (AsnWriter writer = AsnSerializer.Serialize(identifier, AsnEncodingRules.DER))
            {
                const string ExpectedHex =
                    "300D" +
                    "0609608648016503040201" +
                    "0500";

                Assert.Equal(ExpectedHex, writer.Encode().ByteArrayToHex());
            }
        }
Esempio n. 26
0
        public void RemoveSignature(int index)
        {
            if (!_hasData)
            {
                throw new InvalidOperationException(SR.Cryptography_Cms_MessageNotSigned);
            }

            if (index < 0 || index >= _signedData.SignerInfos.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
            }

            AlgorithmIdentifierAsn signerAlgorithm = _signedData.SignerInfos[index].DigestAlgorithm;

            PkcsHelpers.RemoveAt(ref _signedData.SignerInfos, index);

            ConsiderDigestRemoval(signerAlgorithm);
            UpdateMetadata();
        }
Esempio n. 27
0
        public virtual unsafe void ImportRSAPublicKey(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);
                    ReadOnlyMemory <byte> firstValue = reader.PeekEncodedValue();
                    int localRead = firstValue.Length;

                    AlgorithmIdentifierAsn ignored = default;
                    RSAKeyFormatHelper.ReadRsaPublicKey(firstValue, ignored, out RSAParameters rsaParameters);

                    ImportParameters(rsaParameters);

                    bytesRead = localRead;
                }
            }
        }
Esempio n. 28
0
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out EssCertIdV2 decoded)
        {
            decoded = default;
            AsnValueReader      sequenceReader = reader.ReadSequence(expectedTag);
            AsnValueReader      defaultReader;
            ReadOnlySpan <byte> rebindSpan = rebind.Span;
            int offset;
            ReadOnlySpan <byte> tmpSpan;


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence))
            {
                AlgorithmIdentifierAsn.Decode(ref sequenceReader, rebind, out decoded.HashAlgorithm);
            }
            else
            {
                defaultReader = new AsnValueReader(DefaultHashAlgorithm, AsnEncodingRules.DER);
                AlgorithmIdentifierAsn.Decode(ref defaultReader, rebind, out decoded.HashAlgorithm);
            }


            if (sequenceReader.TryReadPrimitiveOctetStringBytes(out tmpSpan))
            {
                decoded.Hash = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
            }
            else
            {
                decoded.Hash = sequenceReader.ReadOctetString();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence))
            {
                CadesIssuerSerial tmpIssuerSerial;
                CadesIssuerSerial.Decode(ref sequenceReader, rebind, out tmpIssuerSerial);
                decoded.IssuerSerial = tmpIssuerSerial;
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory <byte> rebind, out KEKRecipientInfoAsn decoded)
        {
            decoded = default;
            KEKIdentifierAsn       kekIdentifier;
            AlgorithmIdentifierAsn algIdentifier;
            AsnValueReader         sequenceReader = reader.ReadSequence(expectedTag);
            int version;

            if (sequenceReader.TryReadInt32(out version))
            {
                decoded.Version = version;
            }


            KEKIdentifierAsn.Decode(ref sequenceReader, Asn1Tag.Sequence, rebind, out kekIdentifier);
            AlgorithmIdentifierAsn.Decode(ref sequenceReader, Asn1Tag.Sequence, rebind, out algIdentifier);
            var encryptedKey = sequenceReader.ReadOctetString();

            decoded.KEKId            = kekIdentifier;
            decoded.KeyEncryptionAlg = algIdentifier;
            decoded.EncryptedKey     = encryptedKey;
        }
Esempio n. 30
0
            private static byte[]? DecryptContent(
                ReadOnlyMemory <byte> encryptedContent,
                byte[] cek,
                AlgorithmIdentifierAsn contentEncryptionAlgorithm,
                out Exception?exception)
            {
                exception = null;
                int encryptedContentLength = encryptedContent.Length;

                byte[]? encryptedContentArray = CryptoPool.Rent(encryptedContentLength);

                try
                {
                    encryptedContent.CopyTo(encryptedContentArray);

                    using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm))
                        using (ICryptoTransform decryptor = alg.CreateDecryptor(cek, alg.IV))
                        {
                            // If we extend this library to accept additional algorithm providers
                            // then a different array pool needs to be used.
                            Debug.Assert(alg.GetType().Assembly == typeof(Aes).Assembly);

                            return(decryptor.OneShot(
                                       encryptedContentArray,
                                       0,
                                       encryptedContentLength));
                        }
                }
                catch (CryptographicException e)
                {
                    exception = e;
                    return(null);
                }
                finally
                {
                    CryptoPool.Return(encryptedContentArray, encryptedContentLength);
                    encryptedContentArray = null;
                }
            }