Example #1
0
        public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlgorithm)
        {
            string oid;

            if (hashAlgorithm == HashAlgorithmName.SHA256)
            {
                oid = Oids.RsaPkcs1Sha256;
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA384)
            {
                oid = Oids.RsaPkcs1Sha384;
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA512)
            {
                oid = Oids.RsaPkcs1Sha512;
            }
            else
            {
                throw new ArgumentOutOfRangeException(
                          nameof(hashAlgorithm),
                          hashAlgorithm,
                          SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name));
            }

            return(DerEncoder.ConstructSequence(
                       DerEncoder.SegmentedEncodeOid(oid),
                       DerEncoder.SegmentedEncodeNull()));
        }
Example #2
0
        internal static byte[][] SegmentedEncodeSubjectPublicKeyInfo(this PublicKey publicKey)
        {
            if (publicKey == null)
            {
                throw new ArgumentNullException(nameof(publicKey));
            }

            if (publicKey.Oid == null ||
                string.IsNullOrEmpty(publicKey.Oid.Value) ||
                publicKey.EncodedKeyValue == null)
            {
                throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidPublicKey_Object));
            }

            // SubjectPublicKeyInfo::= SEQUENCE  {
            //   algorithm AlgorithmIdentifier,
            //   subjectPublicKey     BIT STRING
            // }
            //
            // AlgorithmIdentifier::= SEQUENCE  {
            //   algorithm OBJECT IDENTIFIER,
            //   parameters ANY DEFINED BY algorithm OPTIONAL
            // }

            byte[][] algorithmIdentifier;

            if (publicKey.EncodedParameters == null)
            {
                algorithmIdentifier = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeOid(publicKey.Oid));
            }
            else
            {
                DerSequenceReader validator =
                    DerSequenceReader.CreateForPayload(publicKey.EncodedParameters.RawData);

                validator.ValidateAndSkipDerValue();

                if (validator.HasData)
                {
                    throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding));
                }

                algorithmIdentifier = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeOid(publicKey.Oid),
                    publicKey.EncodedParameters.RawData.WrapAsSegmentedForSequence());
            }

            return(DerEncoder.ConstructSegmentedSequence(
                       algorithmIdentifier,
                       DerEncoder.SegmentedEncodeBitString(
                           publicKey.EncodedKeyValue.RawData)));
        }
Example #3
0
        internal static byte[][] SegmentedEncodedX509Extension(this X509Extension extension)
        {
            if (extension.Critical)
            {
                return(DerEncoder.ConstructSegmentedSequence(
                           DerEncoder.SegmentedEncodeOid(extension.Oid),
                           DerEncoder.SegmentedEncodeBoolean(extension.Critical),
                           DerEncoder.SegmentedEncodeOctetString(extension.RawData)));
            }

            return(DerEncoder.ConstructSegmentedSequence(
                       DerEncoder.SegmentedEncodeOid(extension.Oid),
                       DerEncoder.SegmentedEncodeOctetString(extension.RawData)));
        }
Example #4
0
        internal static byte[][] SegmentedEncodeAttributeSet(this IEnumerable <X501Attribute> attributes)
        {
            List <byte[][]> encodedAttributes = new List <byte[][]>();

            foreach (X501Attribute attribute in attributes)
            {
                encodedAttributes.Add(
                    DerEncoder.ConstructSegmentedSequence(
                        DerEncoder.SegmentedEncodeOid(attribute.Oid),
                        DerEncoder.ConstructSegmentedPresortedSet(
                            attribute.RawData.WrapAsSegmentedForSequence())));
            }

            return(DerEncoder.ConstructSegmentedSet(encodedAttributes.ToArray()));
        }
Example #5
0
        internal byte[][] EncodeUserPrincipalName(string upn)
        {
            // AnotherName ::= SEQUENCE {
            //   type-id    OBJECT IDENTIFIER,
            //   value[0] EXPLICIT ANY DEFINED BY type-id
            // }

            byte[][] upnUtf8 = DerEncoder.SegmentedEncodeUtf8String(upn.ToCharArray());

            // [0] EXPLICIT
            byte[][] payloadTlv = DerEncoder.ConstructSegmentedSequence(upnUtf8);
            payloadTlv[0][0] = DerSequenceReader.ContextSpecificConstructedTag0;

            byte[][] anotherNameTlv = DerEncoder.ConstructSegmentedSequence(
                DerEncoder.SegmentedEncodeOid(Oids.UserPrincipalName),
                payloadTlv);

            anotherNameTlv[0][0] = (byte)GeneralNameTag.OtherName;

            return(anotherNameTlv);
        }
Example #6
0
        public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlgorithm)
        {
            // If we ever support options in PSS (like MGF-2, if such an MGF is ever invented)
            // Or, more reasonably, supporting a custom value for the salt size.
            if (_padding != RSASignaturePadding.Pss)
            {
                throw new CryptographicException(SR.Cryptography_InvalidPaddingMode);
            }

            uint   cbSalt;
            string digestOid;

            if (hashAlgorithm == HashAlgorithmName.SHA256)
            {
                cbSalt    = 256 / 8;
                digestOid = Oids.Sha256;
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA384)
            {
                cbSalt    = 384 / 8;
                digestOid = Oids.Sha384;
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA512)
            {
                cbSalt    = 512 / 8;
                digestOid = Oids.Sha512;
            }
            else
            {
                throw new ArgumentOutOfRangeException(
                          nameof(hashAlgorithm),
                          hashAlgorithm,
                          SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name));
            }

            // RSASSA-PSS-params comes from RFC 4055, section 3.1:
            // https://tools.ietf.org/html/rfc4055#section-3.1
            //
            // RSASSA-PSS-params  ::=  SEQUENCE  {
            //   hashAlgorithm      [0] HashAlgorithm DEFAULT sha1Identifier,
            //   maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
            //   saltLength         [2] INTEGER DEFAULT 20,
            //   trailerField       [3] INTEGER DEFAULT 1  }
            //
            // mgf1SHA1Identifier  AlgorithmIdentifier  ::= { id-mgf1, sha1Identifier }
            // sha1Identifier  AlgorithmIdentifier  ::=  { id-sha1, NULL }
            // (and similar for SHA256/384/512)
            //
            // RFC 5754 says that the NULL for SHA2 (256/384/512) MUST be omitted
            // (https://tools.ietf.org/html/rfc5754#section-2) (and that you MUST
            // be able to read it even if someone wrote it down)

            // Since we
            //  * don't support SHA-1 in this class
            //  * only support MGF-1
            //  * don't support the MGF PRF being different than hashAlgorithm
            //  * use saltLength==hashLength
            //  * don't allow custom trailer
            // we don't have to worry about any of the DEFAULTs. (specify, specify, specify, omit).

            byte[][] hashAlgorithmAlgId = DerEncoder.ConstructSegmentedSequence(
                DerEncoder.SegmentedEncodeOid(digestOid));

            byte[][] hashAlgorithmField = DerEncoder.ConstructSegmentedSequence(hashAlgorithmAlgId);
            hashAlgorithmField[0][0] = DerSequenceReader.ContextSpecificConstructedTag0;

            byte[][] maskGenField = DerEncoder.ConstructSegmentedSequence(
                DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeOid(Oids.Mgf1),
                    hashAlgorithmAlgId));
            maskGenField[0][0] = DerSequenceReader.ContextSpecificConstructedTag1;

            byte[][] saltLengthField = DerEncoder.ConstructSegmentedSequence(
                DerEncoder.SegmentedEncodeUnsignedInteger(cbSalt));
            saltLengthField[0][0] = DerSequenceReader.ContextSpecificConstructedTag2;

            return(DerEncoder.ConstructSequence(
                       DerEncoder.SegmentedEncodeOid(Oids.RsaSsaPss),
                       // RSASSA-PSS-params
                       DerEncoder.ConstructSegmentedSequence(
                           hashAlgorithmField,
                           maskGenField,
                           saltLengthField)));
        }