コード例 #1
0
        internal byte[][] EncodeUri(Uri uri)
        {
            byte[][] uriTlv = DerEncoder.SegmentedEncodeIA5String(uri.AbsoluteUri.ToCharArray());
            uriTlv[0][0] = (byte)GeneralNameTag.Uri;

            return(uriTlv);
        }
コード例 #2
0
 public X509Extension Build(bool critical = false)
 {
     return(new X509Extension(
                Oids.SubjectAltName,
                DerEncoder.ConstructSequence(_encodedTlvs),
                critical));
 }
コード例 #3
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()));
        }
コード例 #4
0
        internal byte[][] EncodeEmailAddress(string emailAddress)
        {
            byte[][] rfc822NameTlv = DerEncoder.SegmentedEncodeIA5String(emailAddress.ToCharArray());
            rfc822NameTlv[0][0] = (byte)GeneralNameTag.Rfc822Name;

            return(rfc822NameTlv);
        }
コード例 #5
0
        internal byte[][] EncodeDnsName(string dnsName)
        {
            string idnaName = s_idnMapping.GetAscii(dnsName);

            byte[][] dnsNameTlv = DerEncoder.SegmentedEncodeIA5String(idnaName.ToCharArray());
            dnsNameTlv[0][0] = (byte)GeneralNameTag.DnsName;

            return(dnsNameTlv);
        }
コード例 #6
0
        internal byte[][] EncodeIpAddress(IPAddress address)
        {
            byte[] addressBytes = address.GetAddressBytes();

            byte[][] ipAddressTlv = DerEncoder.SegmentedEncodeOctetString(addressBytes);
            ipAddressTlv[0][0] = (byte)GeneralNameTag.IpAddress;

            return(ipAddressTlv);
        }
コード例 #7
0
        public override byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm)
        {
            byte[] ieeeFormat = _key.SignData(data, hashAlgorithm);

            Debug.Assert(ieeeFormat.Length % 2 == 0);
            int segmentLength = ieeeFormat.Length / 2;

            return(DerEncoder.ConstructSequence(
                       DerEncoder.SegmentedEncodeUnsignedInteger(ieeeFormat, 0, segmentLength),
                       DerEncoder.SegmentedEncodeUnsignedInteger(ieeeFormat, segmentLength, segmentLength)));
        }
コード例 #8
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)));
        }
コード例 #9
0
        protected override PublicKey BuildPublicKey()
        {
            ECParameters ecParameters = _key.ExportParameters(false);

            if (!ecParameters.Curve.IsNamed)
            {
                throw new InvalidOperationException(SR.GetString(SR.Cryptography_ECC_NamedCurvesOnly));
            }

            string curveOid = ecParameters.Curve.Oid.Value;

            if (string.IsNullOrEmpty(curveOid))
            {
                string friendlyName = ecParameters.Curve.Oid.FriendlyName;

                // Translate the three curves that were supported Windows 7-8.1, but emit no Oid.Value;
                // otherwise just wash the friendly name back through Oid to see if we can get a value.
                switch (friendlyName)
                {
                case "nistP256":
                    curveOid = Oids.EccCurveSecp256r1;
                    break;

                case "nistP384":
                    curveOid = Oids.EccCurveSecp384r1;
                    break;

                case "nistP521":
                    curveOid = Oids.EccCurveSecp521r1;
                    break;

                default:
                    curveOid = new Oid(friendlyName).Value;
                    break;
                }
            }

            Debug.Assert(ecParameters.Q.X.Length == ecParameters.Q.Y.Length);
            byte[] uncompressedPoint = new byte[1 + ecParameters.Q.X.Length + ecParameters.Q.Y.Length];

            // Uncompressed point (0x04)
            uncompressedPoint[0] = 0x04;

            Buffer.BlockCopy(ecParameters.Q.X, 0, uncompressedPoint, 1, ecParameters.Q.X.Length);
            Buffer.BlockCopy(ecParameters.Q.Y, 0, uncompressedPoint, 1 + ecParameters.Q.X.Length, ecParameters.Q.Y.Length);

            Oid ecPublicKey = new Oid(Oids.Ecc);

            return(new PublicKey(
                       ecPublicKey,
                       new AsnEncodedData(ecPublicKey, DerEncoder.EncodeOid(curveOid)),
                       new AsnEncodedData(ecPublicKey, uncompressedPoint)));
        }
コード例 #10
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)));
        }
コード例 #11
0
ファイル: TbsCertificate.cs プロジェクト: rahku/corefx
        internal byte[] Sign(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            if (signatureGenerator == null)
            {
                throw new ArgumentNullException(nameof(signatureGenerator));
            }

            byte[] encoded   = Encode(signatureGenerator, hashAlgorithm);
            byte[] signature = signatureGenerator.SignData(encoded, hashAlgorithm);

            return(DerEncoder.ConstructSequence(
                       encoded.WrapAsSegmentedForSequence(),
                       signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm).WrapAsSegmentedForSequence(),
                       DerEncoder.SegmentedEncodeBitString(signature)));
        }
コード例 #12
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()));
        }
コード例 #13
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);

            // CertificationRequest ::= SEQUENCE {
            //   certificationRequestInfo CertificationRequestInfo,
            //   signatureAlgorithm AlgorithmIdentifier{ { SignatureAlgorithms } },
            //   signature BIT STRING
            //  }

            byte[] encoded   = Encode();
            byte[] signature = signatureGenerator.SignData(encoded, hashAlgorithm);

            return(DerEncoder.ConstructSequence(
                       encoded.WrapAsSegmentedForSequence(),
                       signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm).WrapAsSegmentedForSequence(),
                       DerEncoder.SegmentedEncodeBitString(signature)));
        }
コード例 #14
0
        protected override PublicKey BuildPublicKey()
        {
            RSAParameters parameters = _key.ExportParameters(false);

            byte[] rsaPublicKey = DerEncoder.ConstructSequence(
                DerEncoder.SegmentedEncodeUnsignedInteger(parameters.Modulus),
                DerEncoder.SegmentedEncodeUnsignedInteger(parameters.Exponent));

            Oid oid = new Oid(Oids.RsaRsa);

            // The OID is being passed to everything here because that's what
            // X509Certificate2.PublicKey does.
            return(new PublicKey(
                       oid,
                       // Encode the DER-NULL even though it is OPTIONAL, because everyone else does.
                       //
                       // This is due to one version of the ASN.1 not including OPTIONAL, and that was
                       // the version that got predominately implemented for RSA. Now it's convention.
                       new AsnEncodedData(oid, new byte[] { 0x05, 0x00 }),
                       new AsnEncodedData(oid, rsaPublicKey)));
        }
コード例 #15
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);
        }
コード例 #16
0
ファイル: TbsCertificate.cs プロジェクト: yangfan111/Mscore
        private static byte[][] EncodeValidityField(DateTimeOffset validityField, string propertyName)
        {
            /* https://tools.ietf.org/html/rfc3280#section-4.1.2.5
             * 4.1.2.5  Validity
             *
             *  The certificate validity period is the time interval during which the
             *  CA warrants that it will maintain information about the status of the
             *  certificate.  The field is represented as a SEQUENCE of two dates:
             *  the date on which the certificate validity period begins (notBefore)
             *  and the date on which the certificate validity period ends
             *  (notAfter).  Both notBefore and notAfter may be encoded as UTCTime or
             *  GeneralizedTime.
             *
             *  CAs conforming to this profile MUST always encode certificate
             *  validity dates through the year 2049 as UTCTime; certificate validity
             *  dates in 2050 or later MUST be encoded as GeneralizedTime.
             *
             *  The validity period for a certificate is the period of time from
             *  notBefore through notAfter, inclusive.
             */

            DateTime utcValue = validityField.UtcDateTime;

            // On the one hand, GeneralizedTime easily goes back to 1000, and possibly to 0000;
            // but on the other, dates before computers are just a bit beyond the pale.
            if (utcValue.Year < 1950)
            {
                throw new ArgumentOutOfRangeException(propertyName, utcValue, SR.GetString(SR.Cryptography_CertReq_DateTooOld));
            }

            // Since the date encoding is effectively a DER rule (ensuring that two encoders
            // produce the same result), no option exists to encode the validity field as a
            // GeneralizedTime when it fits in the UTCTime constraint.
            if (utcValue.Year < 2050)
            {
                return(DerEncoder.SegmentedEncodeUtcTime(utcValue));
            }

            return(DerEncoder.SegmentedEncodeGeneralizedTime(utcValue));
        }
コード例 #17
0
        private byte[] Encode()
        {
            // CertificationRequestInfo::= SEQUENCE {
            //   version INTEGER { v1(0) } (v1,...),
            //   subject Name,
            //   subjectPKInfo SubjectPublicKeyInfo{ { PKInfoAlgorithms } },
            //   attributes[0] Attributes{ { CRIAttributes } }
            // }
            //
            // Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}

            byte[][] attrSet = Attributes.SegmentedEncodeAttributeSet();

            // Replace the tag with ContextSpecific0.
            attrSet[0][0] = DerSequenceReader.ContextSpecificConstructedTag0;

            return(DerEncoder.ConstructSequence(
                       s_encodedVersion,
                       Subject.RawData.WrapAsSegmentedForSequence(),
                       PublicKey.SegmentedEncodeSubjectPublicKeyInfo(),
                       attrSet));
        }
コード例 #18
0
        private static byte[] EncodeAttribute(IEnumerable <X509Extension> extensions)
        {
            if (extensions == null)
            {
                throw new ArgumentNullException(nameof(extensions));
            }

            // extensionRequest ATTRIBUTE ::= {
            //  WITH SYNTAX ExtensionRequest
            //  SINGLE VALUE TRUE
            //  ID pkcs-9-at-extensionRequest
            // }
            //
            // ExtensionRequest ::= Extensions
            //
            // Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
            //
            // Extension  ::=  SEQUENCE  {
            //   extnID      OBJECT IDENTIFIER,
            //   critical    BOOLEAN DEFAULT FALSE,
            //   extnValue   OCTET STRING  }

            List <byte[][]> encodedExtensions = new List <byte[][]>();

            foreach (X509Extension extension in extensions)
            {
                if (extension == null)
                {
                    continue;
                }

                encodedExtensions.Add(extension.SegmentedEncodedX509Extension());
            }

            // The SEQUENCE over the encodedExtensions list is the value of
            // Extensions/ExtensionRequest.
            return(DerEncoder.ConstructSequence(encodedExtensions.ToArray()));
        }
コード例 #19
0
ファイル: TbsCertificate.cs プロジェクト: yangfan111/Mscore
        private byte[] Encode(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            // State validation should be runtime checks if/when this becomes public API
            Debug.Assert(Subject != null);
            Debug.Assert(PublicKey != null);

            // Under a public API model we could allow these to be null for a self-signed case.
            Debug.Assert(SerialNumber != null);
            Debug.Assert(Issuer != null);

            List <byte[][]> encodedFields = new List <byte[][]>();

            byte version = Version;

            if (version != 0)
            {
                byte[][] encodedVersion = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeUnsignedInteger(new[] { version }));

                encodedVersion[0][0] = DerSequenceReader.ContextSpecificConstructedTag0;

                encodedFields.Add(encodedVersion);
            }

            encodedFields.Add(DerEncoder.SegmentedEncodeUnsignedInteger(SerialNumber));

            // SignatureAlgorithm: Use the specified value, or ask the generator (without mutating the class)
            byte[] signatureAlgorithm = SignatureAlgorithm ?? signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm);
            EncodingHelpers.ValidateSignatureAlgorithm(signatureAlgorithm);

            encodedFields.Add(signatureAlgorithm.WrapAsSegmentedForSequence());

            // For public API allowing self-sign ease-of-use, this could be (Issuer ?? Subject).
            encodedFields.Add(Issuer.RawData.WrapAsSegmentedForSequence());

            encodedFields.Add(
                DerEncoder.ConstructSegmentedSequence(
                    EncodeValidityField(NotBefore, nameof(NotBefore)),
                    EncodeValidityField(NotAfter, nameof(NotAfter))));

            encodedFields.Add(Subject.RawData.WrapAsSegmentedForSequence());

            encodedFields.Add(PublicKey.SegmentedEncodeSubjectPublicKeyInfo());

            // Issuer and Subject Unique ID values would go here, if they were supported.

            if (Extensions.Count > 0)
            {
                Debug.Assert(version >= 2);

                List <byte[][]> encodedExtensions = new List <byte[][]>(Extensions.Count);

                // extensions[3]  Extensions OPTIONAL
                //
                // Since this doesn't say IMPLICIT, it will look like
                //
                // A3 [length]
                //   30 [length]
                //     First Extension
                //     Second Extension
                //     ...

                // An interesting quirk of skipping null values here is that
                // Extensions.Count == 0 => no extensions
                // Extensions.ContainsOnly(null) => empty extensions list

                HashSet <string> usedOids = new HashSet <string>(Extensions.Count);

                foreach (X509Extension extension in Extensions)
                {
                    if (extension == null)
                    {
                        continue;
                    }

                    if (!usedOids.Add(extension.Oid.Value))
                    {
                        throw new InvalidOperationException(
                                  SR.GetString(SR.Cryptography_CertReq_DuplicateExtension, extension.Oid.Value));
                    }

                    encodedExtensions.Add(extension.SegmentedEncodedX509Extension());
                }

                byte[][] extensionField = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.ConstructSegmentedSequence(encodedExtensions));
                extensionField[0][0] = DerSequenceReader.ContextSpecificConstructedTag3;

                encodedFields.Add(extensionField);
            }

            return(DerEncoder.ConstructSequence(encodedFields));
        }
コード例 #20
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)));
        }