Inheritance: System.Security.Cryptography.AsnEncodedData
Ejemplo n.º 1
0
 public static string ConvertDistinguishedNameToString(X500DistinguishedName dnString)
 {
     string name = dnString.Name;
     bool flag = false;
     string[] strArray = dnString.Decode(X500DistinguishedNameFlags.UseNewLines).Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
     if (strArray.Length > 0)
     {
         flag = true;
         string pairAndValue = string.Empty;
         for (int i = 0; i < strArray.Length; i++)
         {
             pairAndValue = strArray[i];
             Pair pair = ConvertStringToPair(pairAndValue);
             if (string.Equals((string) pair.First, "CN", StringComparison.OrdinalIgnoreCase))
             {
                 name = (string) pair.Second;
                 flag = false;
                 break;
             }
         }
     }
     else
     {
         name = (string) ConvertStringToPair(name).Second;
         flag = false;
     }
     if (flag)
     {
         name = dnString.Name;
     }
     return name;
 }
Ejemplo n.º 2
0
 public static X509Certificate2 CreateCertificate(X500DistinguishedName subjectName, string friendlyName)
 {
     var key = Create2048RsaKey();
     var cert = CreateSelfSignedCertificate(key, subjectName);
     cert.FriendlyName = friendlyName;
     return cert;
 }
Ejemplo n.º 3
0
        private static X509Certificate2 CreateSelfSignedCertificate(CngKey key, X500DistinguishedName subjectName)
        {
            using (SafeCertContextHandle selfSignedCertHandle = CreateSelfSignedCertificate(key,
                                                                                            true,
                                                                                            subjectName.RawData,
                                                                                            X509CertificateCreationOptions.None, // NONE
                                                                                            RsaSha1Oid,
                                                                                            DateTime.UtcNow,
                                                                                            DateTime.UtcNow.AddYears(1)))
            {
                X509Certificate2 certificate = null;
                bool addedRef = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    selfSignedCertHandle.DangerousAddRef(ref addedRef);
                    certificate = new X509Certificate2(selfSignedCertHandle.DangerousGetHandle());
                }
                finally
                {
                    if (addedRef)
                    {
                        selfSignedCertHandle.DangerousRelease();
                    }
                }

                key.Dispose();

                return certificate;
            }
        }
Ejemplo n.º 4
0
 public SelfSignedCertProperties()
 {
     DateTime today = DateTime.Today;
     ValidFrom = today.AddDays(-1);
     ValidTo = today.AddYears(10);
     Name = new X500DistinguishedName("cn=self");
     KeyBitLength = 4096;
 }
        /// <summary>
        /// Create a RSA based certificate (to be used with encryption) with the given options
        /// </summary>
        /// <param name="buildOptions">Allows for more advanced configuration</param>
        /// <returns>An exportable X509Certificate2 object (with private key)</returns>
        public static X509Certificate2 CreateNewCertificate(RSACertificateBuilderOptions buildOptions)
        {
            if (buildOptions == null)
            {
                throw new ArgumentNullException("buildOptions");
            }

            string keyName = buildOptions.RSAKeyName ?? "RSAKey";

            CngKey objCngKey = null;
            if (CngKey.Exists(keyName))
            {
                objCngKey = CngKey.Open(keyName);
                objCngKey.Delete();
            }

            var creationParameters = new CngKeyCreationParameters();
            creationParameters.ExportPolicy = CngExportPolicies.AllowExport;
            creationParameters.KeyUsage = CngKeyUsages.AllUsages;
            creationParameters.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider;
            var keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(buildOptions.KeySize ?? 4096), CngPropertyOptions.None);
            creationParameters.Parameters.Add(keySizeProperty);

            objCngKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, creationParameters);

            var name = new X500DistinguishedName(buildOptions.FullSubjectName);

            X509CertificateSignatureAlgorithm certAlg;
            switch (buildOptions.HashingMethod ?? HashingMethods.Sha256)
            {
                case HashingMethods.Sha1:
                    certAlg = X509CertificateSignatureAlgorithm.RsaSha1;
                    break;
                case HashingMethods.Sha256:
                    certAlg = X509CertificateSignatureAlgorithm.RsaSha256;
                    break;
                case HashingMethods.Sha384:
                    certAlg = X509CertificateSignatureAlgorithm.RsaSha384;
                    break;
                case HashingMethods.Sha512:
                    certAlg = X509CertificateSignatureAlgorithm.RsaSha512;
                    break;
                default:
                    throw new InvalidOperationException("Selected hashing method is not supported");
            }

            var options = new X509CertificateCreationParameters(name)
            {
                SignatureAlgorithm = certAlg,
                TakeOwnershipOfKey = true
            };

            return objCngKey.CreateSelfSignedCertificate(options);
        }
Ejemplo n.º 6
0
        public override void Reset()
        {
            _lazyRawData = null;
            _lazySignatureAlgorithm = null;
            _lazyVersion = 0;
            _lazySubjectName = null;
            _lazyIssuerName = null;
            _lazyPublicKey = null;
            _lazyPrivateKey = null;
            _lazyExtensions = null;

            base.Reset();
        }
Ejemplo n.º 7
0
        public SimpleCA(string countryCode, string organization, string orgunit, string commonName)
        {
            var distinguishedName = $"C={countryCode};O={organization};OU={orgunit};CN={commonName}";
            //var distinguishedName = "C=US;O=Microsoft;OU=WGA;CN=TedSt";
            //CN={commonName}/OU={organizationUnit}/O={organization}/DC={domain}/STREET={address}/L={locality}/ST={state}/C={country}/DC={domainComponent}"

            var dn = new System.Security.Cryptography.X509Certificates.X500DistinguishedName(
                distinguishedName
                );

            var key = System.Security.Cryptography.RSA.Create();

            key.KeySize = 4096;
            var hash = System.Security.Cryptography.HashAlgorithmName.SHA512;

            var req = new System.Security.Cryptography.X509Certificates.CertificateRequest(dn, key, hash, RSASignaturePadding.Pss);
            var q   = Oid.FromFriendlyName("", OidGroup.EnhancedKeyUsage);

            Oid.FromOidValue("", OidGroup.EnhancedKeyUsage);
            var r = new OidCollection();

            r.Add(q);
            var v = new X509EnhancedKeyUsageExtension(r, false);

            req.CertificateExtensions.Add(SetEnhancedKeyUsage(keyCertSign: true));
            req.CertificateExtensions.Add(SetBasicConstraints(true));
            req.CertificateExtensions.Add(v);
            var now       = DateTimeOffset.UtcNow;
            var startDate = now - TimeSpan.FromMinutes(5);
            var endDate   = DateTimeOffset.UtcNow + TimeSpan.FromDays(365.25 * 10);

            rootCert = req.CreateSelfSigned(startDate, endDate);
            rootKey  = key;

            var rootKeyChain = rootCert.Export(X509ContentType.Pkcs12);
        }
 public X500DistinguishedName(X500DistinguishedName distinguishedName) : base(distinguishedName)
 {
     this.m_distinguishedName = distinguishedName.Name;
 }
Ejemplo n.º 9
0
        void m_decode(Byte[] rawData)
        {
            try {
                Type = X509CrlType.BaseCrl;
                var signedInfo = new SignedContentBlob(rawData, ContentBlobType.SignedBlob);
                // signature and alg
                signature          = signedInfo.Signature.Value;
                sigUnused          = signedInfo.Signature.UnusedBits;
                SignatureAlgorithm = signedInfo.SignatureAlgorithm.AlgorithmId;
                // tbs
                Asn1Reader asn = new Asn1Reader(signedInfo.ToBeSignedData);
                if (!asn.MoveNext())
                {
                    throw new Asn1InvalidTagException();
                }
                // version
                if (asn.Tag == (Byte)Asn1Type.INTEGER)
                {
                    Version = (Int32)Asn1Utils.DecodeInteger(asn.GetTagRawData()) + 1;
                    asn.MoveNextCurrentLevel();
                }
                else
                {
                    Version = 1;
                }
                // hash algorithm
                var h = new AlgorithmIdentifier(asn.GetTagRawData());
                if (h.AlgorithmId.Value != SignatureAlgorithm.Value)
                {
                    throw new CryptographicException("Algorithm mismatch.");
                }
                if (!asn.MoveNextCurrentLevel())
                {
                    throw new Asn1InvalidTagException();
                }
                // issuer
                IssuerName = new X500DistinguishedName(asn.GetTagRawData());
                // NextUpdate, RevokedCerts and Extensions are optional. Ref: RFC5280, p.118
                if (!asn.MoveNextCurrentLevel())
                {
                    throw new Asn1InvalidTagException();
                }
                switch (asn.Tag)
                {
                case (Byte)Asn1Type.UTCTime:
                    ThisUpdate = new Asn1UtcTime(asn.GetTagRawData()).Value;
                    break;

                case (Byte)Asn1Type.GeneralizedTime:
                    ThisUpdate = Asn1Utils.DecodeGeneralizedTime(asn.GetTagRawData());
                    break;

                default:
                    throw new Asn1InvalidTagException();
                }
                if (!asn.MoveNextCurrentLevel())
                {
                    return;
                }
                switch (asn.Tag)
                {
                case (Byte)Asn1Type.UTCTime:
                case (Byte)Asn1Type.GeneralizedTime:
                    switch (asn.Tag)
                    {
                    case (Byte)Asn1Type.UTCTime:
                        NextUpdate = new Asn1UtcTime(asn.GetTagRawData()).Value;
                        break;

                    case (Byte)Asn1Type.GeneralizedTime:
                        NextUpdate = Asn1Utils.DecodeGeneralizedTime(asn.GetTagRawData());
                        break;

                    default:
                        throw new Asn1InvalidTagException();
                    }
                    if (!asn.MoveNextCurrentLevel())
                    {
                        return;
                    }
                    if (asn.Tag == 48)
                    {
                        getRevCerts(asn);
                        if (!asn.MoveNextCurrentLevel())
                        {
                            return;
                        }
                        getExts(asn);
                    }
                    else
                    {
                        getExts(asn);
                    }
                    break;

                case 48:
                    if (asn.Tag == 48)
                    {
                        getRevCerts(asn);
                        if (!asn.MoveNextCurrentLevel())
                        {
                            return;
                        }
                        getExts(asn);
                    }
                    else
                    {
                        getExts(asn);
                    }
                    break;

                default:
                    getExts(asn);
                    break;
                }
            } catch (Exception e) {
                throw new CryptographicException("Cannot find the requested object.", e);
            }
        }
Ejemplo n.º 10
0
 private static String FormatX509Name(X500DistinguishedName name)
 {
     Asn1StreamParser parser = new Asn1StreamParser(name.RawData);
     X509Name _name = X509Name.GetInstance(parser.ReadObject().ToAsn1Object());
     return _name.ToString(true, X509Name.RFC1779Symbols);
 }
Ejemplo n.º 11
0
        //
        // Used only by client SSL code, never returns null.
        //
        private string[] GetIssuers()
        {
            string[] issuers = new string[0];

            if (IsValidContext)
            {
#if MONO_NOT_IMPLEMENTED
                IssuerListInfoEx issuerList = (IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(m_SecModule, m_SecurityContext, ContextAttribute.IssuerListInfoEx);
                try
                {
                    if (issuerList.cIssuers>0) {
                        unsafe {
                            uint count = issuerList.cIssuers;
                            issuers = new string[issuerList.cIssuers];
                            _CERT_CHAIN_ELEMENT* pIL = (_CERT_CHAIN_ELEMENT*)issuerList.aIssuers.DangerousGetHandle();
                            for (uint i =0; i<count; ++i) {
                                _CERT_CHAIN_ELEMENT* pIL2 = pIL + i;
                                uint size = pIL2->cbSize;
                                byte* ptr = (byte*)(pIL2->pCertContext);
                                byte[] x = new byte[size];
                                for (uint j=0; j<size; j++) {
                                    x[j] = *(ptr + j);
                                }
                                // Oid oid = new Oid();
                                // oid.Value = "1.3.6.1.5.5.7.3.2";
                                // Value of issuers[i] can be an empty string when size of x is 0.
                                X500DistinguishedName x500DistinguishedName = new X500DistinguishedName(x);
                                issuers[i] = x500DistinguishedName.Name;
                                GlobalLog.Print("SecureChannel#" + ValidationHelper.HashString(this) + "::GetIssuers() IssuerListEx[" + i + "]:" + issuers[i]);
                            }
                        }
                    }
                }
                finally
                {
                    if (issuerList.aIssuers != null)
                    {
                        issuerList.aIssuers.Close();
                    }
                }
#endif
            }
            return issuers;
        }
Ejemplo n.º 12
0
		public void RFC3280MandatoryAttributeTypes ()
		{
			string expected = "dnQualifier=CA, OID.2.5.4.5=345, S=Maryland, DC=testcertificates, DC=gov, O=Test Certificates, C=US";
			X509Certificate2 cert = new X509Certificate2 (RFC3280MandatoryAttributeTypesCACert_crt);
			// note: strangely the (also CryptoAPI based) certificate viewer in Windows seems to resolve 2.5.4.5 as "Serial Number"
			Assert.AreEqual (expected, cert.SubjectName.Name, "SubjectName");
			X500DistinguishedName build = new X500DistinguishedName (expected);
			Assert.AreEqual (expected, build.Name, "Name");
		}
Ejemplo n.º 13
0
		public void T61String ()
		{
			// http://bugzilla.ximian.com/show_bug.cgi?id=77295
			byte[] sn = { 0x30, 0x81, 0xB5, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 
				0x03, 0x55, 0x04, 0x0A, 0x14, 0x24, 0x48, 0x65, 0x64, 0x65, 0x62, 0x79, 0x27, 0x73, 0x20, 0x4D, 0xF8, 0x62, 0x65, 0x6C, 0x68, 0x61, 
				0x6E, 0x64, 0x65, 0x6C, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x56, 0x52, 0x3A, 0x31, 0x33, 0x34, 0x37, 0x31, 0x39, 0x36, 0x37, 0x31, 0x2F, 
				0x30, 0x2D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x26, 0x48, 0x65, 0x64, 0x65, 0x62, 0x79, 0x27, 0x73, 0x20, 0x4D, 0xF8, 0x62, 0x65, 
				0x6C, 0x68, 0x61, 0x6E, 0x64, 0x65, 0x6C, 0x20, 0x2D, 0x20, 0x53, 0x61, 0x6C, 0x67, 0x73, 0x61, 0x66, 0x64, 0x65, 0x6C, 0x69, 0x6E, 
				0x67, 0x65, 0x6E, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x0F, 0x76, 0x68, 
				0x6D, 0x40, 0x75, 0x73, 0x65, 0x2E, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x64, 0x6B, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x05, 
				0x13, 0x1D, 0x43, 0x56, 0x52, 0x3A, 0x31, 0x33, 0x34, 0x37, 0x31, 0x39, 0x36, 0x37, 0x2D, 0x55, 0x49, 0x44, 0x3A, 0x31, 0x32, 0x31, 
				0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
			X500DistinguishedName dn = new X500DistinguishedName (sn);
			string subject = "OID.2.5.4.5=CVR:13471967-UID:121212121212, [email protected], CN=Hedeby's Møbelhandel - Salgsafdelingen, O=Hedeby's Møbelhandel // CVR:13471967, C=DK";
			Assert.AreEqual (subject, dn.Name, "Name");
		}
Ejemplo n.º 14
0
        public string GetNameInfo(X509NameType nameType, bool forIssuer)
        {
            // Algorithm behaviors (pseudocode).  When forIssuer is true, replace "Subject" with "Issuer" and
            // SAN (Subject Alternative Names) with IAN (Issuer Alternative Names).
            //
            // SimpleName: Subject[CN] ?? Subject[OU] ?? Subject[O] ?? Subject[E] ?? Subject.Rdns.FirstOrDefault() ??
            // SAN.Entries.FirstOrDefault(type == GEN_EMAIL);
            // EmailName: SAN.Entries.FirstOrDefault(type == GEN_EMAIL) ?? Subject[E];
            // UpnName: SAN.Entries.FirsOrDefaultt(type == GEN_OTHER && entry.AsOther().OID == szOidUpn).AsOther().Value;
            // DnsName: SAN.Entries.FirstOrDefault(type == GEN_DNS) ?? Subject[CN];
            // DnsFromAlternativeName: SAN.Entries.FirstOrDefault(type == GEN_DNS);
            // UrlName: SAN.Entries.FirstOrDefault(type == GEN_URI);

            if (nameType == X509NameType.SimpleName)
            {
                X500DistinguishedName name = forIssuer ? Issuer : Subject;
                string?candidate           = GetSimpleNameInfo(name);

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

            // Check the Subject Alternative Name (or Issuer Alternative Name) for the right value;
            {
                string          extensionId = forIssuer ? Oids.IssuerAltName : Oids.SubjectAltName;
                GeneralNameType?matchType   = null;
                string?         otherOid    = null;

                // Currently all X509NameType types have a path where they look at the SAN/IAN,
                // but we need to figure out which kind they want.
                switch (nameType)
                {
                case X509NameType.DnsName:
                case X509NameType.DnsFromAlternativeName:
                    matchType = GeneralNameType.DnsName;
                    break;

                case X509NameType.SimpleName:
                case X509NameType.EmailName:
                    matchType = GeneralNameType.Email;
                    break;

                case X509NameType.UpnName:
                    matchType = GeneralNameType.OtherName;
                    otherOid  = Oids.UserPrincipalName;
                    break;

                case X509NameType.UrlName:
                    matchType = GeneralNameType.UniformResourceIdentifier;
                    break;
                }

                if (matchType.HasValue)
                {
                    foreach (X509Extension extension in Extensions)
                    {
                        if (extension.Oid !.Value == extensionId)
                        {
                            string?candidate = FindAltNameMatch(extension.RawData, matchType.Value, otherOid);

                            if (candidate != null)
                            {
                                return(candidate);
                            }
                        }
                    }
                }
                else
                {
                    Debug.Fail($"Unresolved matchType for X509NameType.{nameType}");
                }
            }

            // Subject-based fallback
            {
                string?expectedKey = null;

                switch (nameType)
                {
                case X509NameType.EmailName:
                    expectedKey = Oids.EmailAddress;
                    break;

                case X509NameType.DnsName:
                    // Note: This does not include DnsFromAlternativeName, since
                    // the subject (or issuer) is not the Alternative Name.
                    expectedKey = Oids.CommonName;
                    break;
                }

                if (expectedKey != null)
                {
                    X500DistinguishedName name = forIssuer ? Issuer : Subject;

                    foreach (var kvp in ReadReverseRdns(name))
                    {
                        if (kvp.Key == expectedKey)
                        {
                            return(kvp.Value);
                        }
                    }
                }
            }

            return("");
        }
Ejemplo n.º 15
0
		public void Constructor_X500DistinguishedName ()
		{
			X500DistinguishedName dn = new X500DistinguishedName (x509a.IssuerName);
			Assert.IsNotNull (dn.Oid, "Oid");
			Assert.IsNull (dn.Oid.Value, "Oid.Value");
			Assert.IsNull (dn.Oid.FriendlyName, "Oid.FriendlyName");
			RsaIssuer (dn);
		}
Ejemplo n.º 16
0
 public X509Certificate2 Create(X500DistinguishedName issuerName, X509SignatureGenerator generator, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, byte[] serialNumber) => throw new PlatformNotSupportedException();
Ejemplo n.º 17
0
 public X500DistinguishedName(X500DistinguishedName distinguishedName)
     : base(distinguishedName)
 {
     _lazyDistinguishedName = distinguishedName.Name;
 }
Ejemplo n.º 18
0
 public CertificateRequest(X500DistinguishedName subjectName, PublicKey publicKey, HashAlgorithmName hashAlgorithm) => throw new PlatformNotSupportedException();
Ejemplo n.º 19
0
 public CertificateRequest(X500DistinguishedName subjectName, RSA key, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) => throw new PlatformNotSupportedException();
Ejemplo n.º 20
0
        /// <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>
        ///   The ASN.1 DER-encoded certificate, suitable to be passed to <see cref="X509Certificate2(byte[])"/>.
        /// </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"/> is null or 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,
            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);
            }

            TbsCertificateAsn tbsCertificate = new TbsCertificateAsn
            {
                Version              = 2,
                SerialNumber         = NormalizeSerialNumber(serialNumber),
                SignatureAlgorithm   = signatureAlgorithmAsn,
                Issuer               = issuerName.RawData,
                SubjectPublicKeyInfo = new SubjectPublicKeyInfoAsn
                {
                    Algorithm = new AlgorithmIdentifierAsn
                    {
                        Algorithm  = PublicKey.Oid,
                        Parameters = PublicKey.EncodedParameters.RawData,
                    },
                    SubjectPublicKey = PublicKey.EncodedKeyValue.RawData,
                },
                Validity = new ValidityAsn(notBefore, notAfter),
                Subject  = SubjectName.RawData,
            };

            if (CertificateExtensions.Count > 0)
            {
                HashSet <string>        usedOids      = new HashSet <string>(CertificateExtensions.Count);
                List <X509ExtensionAsn> extensionAsns = new List <X509ExtensionAsn>(CertificateExtensions.Count);

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

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

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

                    extensionAsns.Add(new X509ExtensionAsn(extension, false));
                }

                tbsCertificate.Extensions = extensionAsns.ToArray();
            }

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

                    byte[]         encodedTbsCertificate = writer.Encode();
                    CertificateAsn certificate           = new CertificateAsn
                    {
                        TbsCertificate     = tbsCertificate,
                        SignatureAlgorithm = signatureAlgorithmAsn,
                        SignatureValue     = generator.SignData(encodedTbsCertificate, HashAlgorithm),
                    };

                    certificate.Encode(signedWriter);
                    return(new X509Certificate2(signedWriter.Encode()));
                }
        }
Ejemplo n.º 21
0
		// *** certificate chain/path validation stuff ***

		// Currently a subset of RFC3280 (hopefully a full implementation someday)
		private void ValidateChain (X509ChainStatusFlags flag)
		{
			// 'n' should be the root certificate... 
			int n = elements.Count - 1;
			X509Certificate2 certificate = elements [n].Certificate;

			// ... and, if so, must be treated outside the chain... 
			if (((flag & X509ChainStatusFlags.PartialChain) == 0)) {
				Process (n);
				// deal with the case where the chain == the root certificate 
				// (which isn't for RFC3280) part of the chain
				if (n == 0) {
					elements [0].UncompressFlags ();
					return;
				}
				// skip the root certificate when processing the chain (in 6.1.3)
				n--;
			}
			// ... unless the chain is a partial one (then we start with that one)

			// 6.1.1 - Inputs
			// 6.1.1.a - a prospective certificate path of length n (i.e. elements)
			// 6.1.1.b - the current date/time (i.e. ChainPolicy.VerificationTime)
			// 6.1.1.c - user-initial-policy-set (i.e. ChainPolicy.CertificatePolicy)
			// 6.1.1.d - the trust anchor information (i.e. certificate, unless it's a partial chain)
			// 6.1.1.e - initial-policy-mapping-inhibit (NOT SUPPORTED BY THE API)
			// 6.1.1.f - initial-explicit-policy (NOT SUPPORTED BY THE API)
			// 6.1.1.g - initial-any-policy-inhibit (NOT SUPPORTED BY THE API)

			// 6.1.2 - Initialization (incomplete)
			// 6.1.2.a-f - policy stuff, some TODO, some not supported
			// 6.1.2.g - working public key algorithm
//			working_public_key_algorithm = certificate.PublicKey.Oid.Value;
			// 6.1.2.h-i - our key contains both the "working public key" and "working public key parameters" data
			working_public_key = certificate.PublicKey.Key;
			// 6.1.2.j - working issuer name
			working_issuer_name = certificate.IssuerName;
			// 6.1.2.k - this integer is initialized to n, is decremented for each non-self-issued, certificate and
			//	     may be reduced to the value in the path length constraint field
			max_path_length = n;

			// 6.1.3 - Basic Certificate Processing
			// note: loop looks reversed (the list is) but we process this part just like RFC3280 does
			for (int i = n; i > 0; i--) {
				Process (i);
				// 6.1.4 - preparation for certificate i+1 (for not with i+1, or i-1 in our loop)
				PrepareForNextCertificate (i);
			}
			Process (0);

			// 6.1.3.a.3 - revocation checks
			CheckRevocationOnChain (flag);

			// 6.1.5 - Wrap-up procedure
			WrapUp ();
		}
Ejemplo n.º 22
0
        private void Process(int n)
        {
            X509ChainElement element     = elements [n];
            X509Certificate2 certificate = element.Certificate;

            // pre-step: DSA certificates may inherit the parameters of their CA
            if ((n != elements.Count - 1) && (certificate.MonoCertificate.KeyAlgorithm == "1.2.840.10040.4.1"))
            {
                if (certificate.MonoCertificate.KeyAlgorithmParameters == null)
                {
                    X509Certificate2 parent = elements [n + 1].Certificate;
                    certificate.MonoCertificate.KeyAlgorithmParameters = parent.MonoCertificate.KeyAlgorithmParameters;
                }
            }

            bool root = (working_public_key == null);

            // 6.1.3.a.1 - check signature (with special case to deal with root certificates)
            if (!IsSignedWith(certificate, root ? certificate.PublicKey.Key : working_public_key))
            {
                // another special case where only an end-entity is available and can't be verified.
                // In this case we do not report an invalid signature (since this is unknown)
                if (root || (n != elements.Count - 1) || IsSelfIssued(certificate))
                {
                    element.StatusFlags |= X509ChainStatusFlags.NotSignatureValid;
                }
            }

            // 6.1.3.a.2 - check validity period
            if ((ChainPolicy.VerificationTime < certificate.NotBefore) ||
                (ChainPolicy.VerificationTime > certificate.NotAfter))
            {
                element.StatusFlags |= X509ChainStatusFlags.NotTimeValid;
            }
            // TODO - for X509ChainStatusFlags.NotTimeNested (needs global structure)

            // note: most of them don't apply to the root certificate
            if (root)
            {
                return;
            }

            // 6.1.3.a.3 - revocation check (we're doing at the last stage)
            // note: you revoke a trusted root by removing it from your trusted store (i.e. no CRL can do this job)

            // 6.1.3.a.4 - check certificate issuer name
            if (!X500DistinguishedName.AreEqual(certificate.IssuerName, working_issuer_name))
            {
                // NOTE: this is not the "right" error flag, but it's the closest one defined
                element.StatusFlags |= X509ChainStatusFlags.InvalidNameConstraints;
            }

            if (!IsSelfIssued(certificate) && (n != 0))
            {
                // TODO 6.1.3.b - subject name in the permitted_subtrees ...
                // TODO 6.1.3.c - subject name not within excluded_subtrees...

                // TODO - check for X509ChainStatusFlags.InvalidNameConstraint
                // TODO - check for X509ChainStatusFlags.HasNotSupportedNameConstraint
                // TODO - check for X509ChainStatusFlags.HasNotPermittedNameConstraint
                // TODO - check for X509ChainStatusFlags.HasExcludedNameConstraint
            }

            // TODO 6.1.3.d - check if certificate policies extension is present
            //if (false) {
            // TODO - for X509ChainStatusFlags.InvalidPolicyConstraints
            //	using X509ChainPolicy.ApplicationPolicy and X509ChainPolicy.CertificatePolicy

            // TODO - check for X509ChainStatusFlags.NoIssuanceChainPolicy

            //} else {
            // TODO 6.1.3.e - set valid_policy_tree to NULL
            //}

            // TODO 6.1.3.f - verify explict_policy > 0 if valid_policy_tree != NULL
        }
Ejemplo n.º 23
0
        private static unsafe CertificateRequest LoadSigningRequest(
            ReadOnlySpan <byte> pkcs10,
            bool permitTrailingData,
            HashAlgorithmName signerHashAlgorithm,
            out int bytesConsumed,
            CertificateRequestLoadOptions options,
            RSASignaturePadding?signerSignaturePadding)
        {
            ArgumentException.ThrowIfNullOrEmpty(signerHashAlgorithm.Name, nameof(signerHashAlgorithm));

            if ((options & ~AllOptions) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(options), options, SR.Argument_InvalidFlag);
            }

            bool skipSignatureValidation =
                (options & CertificateRequestLoadOptions.SkipSignatureValidation) != 0;

            bool unsafeLoadCertificateExtensions =
                (options & CertificateRequestLoadOptions.UnsafeLoadCertificateExtensions) != 0;

            try
            {
                AsnValueReader outer         = new AsnValueReader(pkcs10, AsnEncodingRules.DER);
                int            encodedLength = outer.PeekEncodedValue().Length;

                AsnValueReader     pkcs10Asn = outer.ReadSequence();
                CertificateRequest req;

                if (!permitTrailingData)
                {
                    outer.ThrowIfNotEmpty();
                }

                fixed(byte *p10ptr = pkcs10)
                {
                    using (PointerMemoryManager <byte> manager = new PointerMemoryManager <byte>(p10ptr, encodedLength))
                    {
                        ReadOnlyMemory <byte>       rebind             = manager.Memory;
                        ReadOnlySpan <byte>         encodedRequestInfo = pkcs10Asn.PeekEncodedValue();
                        CertificationRequestInfoAsn requestInfo;
                        AlgorithmIdentifierAsn      algorithmIdentifier;
                        ReadOnlySpan <byte>         signature;
                        int signatureUnusedBitCount;

                        CertificationRequestInfoAsn.Decode(ref pkcs10Asn, rebind, out requestInfo);
                        AlgorithmIdentifierAsn.Decode(ref pkcs10Asn, rebind, out algorithmIdentifier);

                        if (!pkcs10Asn.TryReadPrimitiveBitString(out signatureUnusedBitCount, out signature))
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                        }

                        pkcs10Asn.ThrowIfNotEmpty();

                        if (requestInfo.Version < 0)
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                        }

                        // They haven't bumped from v0 to v1 as of 2022.
                        const int MaxSupportedVersion = 0;

                        if (requestInfo.Version != MaxSupportedVersion)
                        {
                            throw new CryptographicException(
                                      SR.Format(
                                          SR.Cryptography_CertReq_Load_VersionTooNew,
                                          requestInfo.Version,
                                          MaxSupportedVersion));
                        }

                        PublicKey publicKey = PublicKey.DecodeSubjectPublicKeyInfo(ref requestInfo.SubjectPublicKeyInfo);

                        if (!skipSignatureValidation)
                        {
                            // None of the supported signature algorithms support signatures that are not full bytes.
                            // So, shortcut the verification on the bit length
                            if (signatureUnusedBitCount != 0 ||
                                !VerifyX509Signature(encodedRequestInfo, signature, publicKey, algorithmIdentifier))
                            {
                                throw new CryptographicException(SR.Cryptography_CertReq_SignatureVerificationFailed);
                            }
                        }

                        X500DistinguishedName subject = new X500DistinguishedName(requestInfo.Subject.Span);

                        req = new CertificateRequest(
                            subject,
                            publicKey,
                            signerHashAlgorithm,
                            signerSignaturePadding);

                        if (requestInfo.Attributes is not null)
                        {
                            bool foundCertExt = false;

                            foreach (AttributeAsn attr in requestInfo.Attributes)
                            {
                                if (attr.AttrType == Oids.Pkcs9ExtensionRequest)
                                {
                                    if (foundCertExt)
                                    {
                                        throw new CryptographicException(
                                                  SR.Cryptography_CertReq_Load_DuplicateExtensionRequests);
                                    }

                                    foundCertExt = true;

                                    if (attr.AttrValues.Length != 1)
                                    {
                                        throw new CryptographicException(
                                                  SR.Cryptography_CertReq_Load_DuplicateExtensionRequests);
                                    }

                                    AsnValueReader extsReader = new AsnValueReader(
                                        attr.AttrValues[0].Span,
                                        AsnEncodingRules.DER);

                                    AsnValueReader exts = extsReader.ReadSequence();
                                    extsReader.ThrowIfNotEmpty();

                                    // Minimum length is 1, so do..while
                                    do
                                    {
                                        X509ExtensionAsn.Decode(ref exts, rebind, out X509ExtensionAsn extAsn);

                                        if (unsafeLoadCertificateExtensions)
                                        {
                                            X509Extension ext = new X509Extension(
                                                extAsn.ExtnId,
                                                extAsn.ExtnValue.Span,
                                                extAsn.Critical);

                                            X509Extension?rich =
                                                X509Certificate2.CreateCustomExtensionIfAny(extAsn.ExtnId);

                                            if (rich is not null)
                                            {
                                                rich.CopyFrom(ext);
                                                req.CertificateExtensions.Add(rich);
                                            }
                                            else
                                            {
                                                req.CertificateExtensions.Add(ext);
                                            }
                                        }
                                    } while (exts.HasData);
                                }
                                else
                                {
                                    if (attr.AttrValues.Length == 0)
                                    {
                                        throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                                    }

                                    foreach (ReadOnlyMemory <byte> val in attr.AttrValues)
                                    {
                                        req.OtherRequestAttributes.Add(
                                            new AsnEncodedData(attr.AttrType, val.Span));
                                    }
                                }
                            }
                        }
                    }
                }

                bytesConsumed = encodedLength;
                return(req);
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
Ejemplo n.º 24
0
        // CTL == Certificate Trust List / NOT SUPPORTED
        // TODO - check for X509ChainStatusFlags.CtlNotTimeValid
        // TODO - check for X509ChainStatusFlags.CtlNotSignatureValid
        // TODO - check for X509ChainStatusFlags.CtlNotValidForUsage

        private void PrepareForNextCertificate(int n)
        {
            X509ChainElement element     = elements [n];
            X509Certificate2 certificate = element.Certificate;

            // TODO 6.1.4.a-b

            // 6.1.4.c
            working_issuer_name = certificate.SubjectName;
            // 6.1.4.d-e - our key includes both the public key and it's parameters
            working_public_key = certificate.PublicKey.Key;
            // 6.1.4.f
//			working_public_key_algorithm = certificate.PublicKey.Oid.Value;

            // TODO 6.1.4.g-j

            // 6.1.4.k - Verify that the certificate is a CA certificate
            X509BasicConstraintsExtension bce = (X509BasicConstraintsExtension)certificate.Extensions["2.5.29.19"];

            if (bce != null)
            {
                if (!bce.CertificateAuthority)
                {
                    element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                }
            }
            else if (certificate.Version >= 3)
            {
                // recent (v3+) CA certificates must include BCE
                element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
            }

            // 6.1.4.l - if the certificate isn't self-issued...
            if (!IsSelfIssued(certificate))
            {
                // ... verify that max_path_length > 0
                if (max_path_length > 0)
                {
                    max_path_length--;
                }
                else
                {
                    // to match MS the reported status must be against the certificate
                    // with the BCE and not where the path is too long. It also means
                    // that this condition has to be reported only once
                    if (bce_restriction != null)
                    {
                        bce_restriction.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
                    }
                }
            }

            // 6.1.4.m - if pathLengthConstraint is present...
            if ((bce != null) && (bce.HasPathLengthConstraint))
            {
                // ... and is less that max_path_length, set max_path_length to it's value
                if (bce.PathLengthConstraint < max_path_length)
                {
                    max_path_length = bce.PathLengthConstraint;
                    bce_restriction = element;
                }
            }

            // 6.1.4.n - if key usage extension is present...
            X509KeyUsageExtension kue = (X509KeyUsageExtension)certificate.Extensions["2.5.29.15"];

            if (kue != null)
            {
                // ... verify keyCertSign is set
                X509KeyUsageFlags success = X509KeyUsageFlags.KeyCertSign;
                if ((kue.KeyUsages & success) != success)
                {
                    element.StatusFlags |= X509ChainStatusFlags.NotValidForUsage;
                }
            }

            // 6.1.4.o - recognize and process other critical extension present in the certificate
            ProcessCertificateExtensions(element);
        }
Ejemplo n.º 25
0
		public void Decode_Separators ()
		{
			string semicolons = "C=US; O=\"RSA Data Security, Inc.\"; OU=Secure Server Certification Authority";
			string newline = String.Format ("C=US{0}O=\"RSA Data Security, Inc.\"{0}OU=Secure Server Certification Authority", Environment.NewLine);
			X500DistinguishedName dn = new X500DistinguishedName (rname, X500DistinguishedNameFlags.None);
			Assert.AreEqual (rname, dn.Name, "Name");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.None), "Decode(None)");

			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.UseCommas), "Decode(UseCommas)");
			Assert.AreEqual (semicolons, dn.Decode (X500DistinguishedNameFlags.UseSemicolons), "Decode(UseCommas|UseSemicolons)");
			Assert.AreEqual (newline, dn.Decode (X500DistinguishedNameFlags.UseNewLines), "Decode(UseNewLines)");

			Assert.AreEqual (semicolons, dn.Decode (X500DistinguishedNameFlags.UseCommas | X500DistinguishedNameFlags.UseSemicolons), "Decode(UseCommas|UseSemicolons)");
			Assert.AreEqual (semicolons, dn.Decode (X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.UseSemicolons), "Decode(UseNewLines|UseSemicolons)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.UseCommas | X500DistinguishedNameFlags.UseNewLines), "Decode(UseCommas|UseNewLines)");
		}
Ejemplo n.º 26
0
        private void Decode()
        {
            if (_decoded)
            {
                return;
            }

            // AuthorityKeyIdentifier ::= SEQUENCE {
            //   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
            //   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
            //   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
            //
            // KeyIdentifier ::= OCTET STRING

            string keyId = null;
            X500DistinguishedName firstIssuerName = null;
            DerSequenceReader     reader          = new DerSequenceReader(RawData);

            byte[] serialNumber = null;

            // Primitive Context 0
            const byte KeyIdTag = DerSequenceReader.ContextSpecificTagFlag | 0;
            // Constructed Context 1
            const byte CertIssuerTag = DerSequenceReader.ContextSpecificConstructedTag1;
            // Primitive Context 2
            const byte CertSerialTag = DerSequenceReader.ContextSpecificTagFlag | 2;

            if (reader.HasTag(KeyIdTag))
            {
                keyId = reader.ReadOctetString().ToHexStringUpper();
            }

            if (reader.HasTag(CertIssuerTag))
            {
                DerSequenceReader generalNames = reader.ReadSequence();

                while (generalNames.HasData)
                {
                    const byte DirectoryNameTag = DerSequenceReader.ConstructedFlag |
                                                  (byte)GeneralNameEncoder.GeneralNameTag.DirectoryName;

                    if (firstIssuerName == null && generalNames.HasTag(DirectoryNameTag))
                    {
                        firstIssuerName = new X500DistinguishedName(generalNames.ReadNextEncodedValue());
                    }

                    reader.ValidateAndSkipDerValue();
                }
            }

            if (reader.HasTag(CertSerialTag))
            {
                serialNumber = reader.ReadOctetString();
            }

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

            _firstIssuerName = firstIssuerName;
            _serialNumber    = serialNumber;
            _keyIdentifier   = keyId;
            _decoded         = true;
        }
Ejemplo n.º 27
0
		public void RFC3280OptionalAttributeTypes ()
		{
			string expected = "T=M.D., OID.2.5.4.44=III, SN=CA, OID.2.5.4.65=Fictitious, I=Q, G=John, L=Gaithersburg, O=Test Certificates, C=US";
			X509Certificate2 cert = new X509Certificate2 (RFC3280OptionalAttributeTypesCACert_crt);
			Assert.AreEqual (expected, cert.SubjectName.Name, "SubjectName");
			X500DistinguishedName build = new X500DistinguishedName (expected);
			Assert.AreEqual (expected, build.Name, "Name");
		}
        //
        // Used only by client SSL code, never returns null.
        //
        internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
        {
            Interop.SspiCli.IssuerListInfoEx issuerList =
                (Interop.SspiCli.IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(
                    GlobalSSPI.SSPISecureChannel,
                    securityContext,
                    Interop.SspiCli.ContextAttribute.IssuerListInfoEx);

            string[] issuers = Array.Empty<string>();

            try
            {
                if (issuerList.cIssuers > 0)
                {
                    unsafe
                    {
                        uint count = issuerList.cIssuers;
                        issuers = new string[issuerList.cIssuers];
                        Interop.SspiCli._CERT_CHAIN_ELEMENT* pIL = (Interop.SspiCli._CERT_CHAIN_ELEMENT*)issuerList.aIssuers.DangerousGetHandle();
                        for (int i = 0; i < count; ++i)
                        {
                            Interop.SspiCli._CERT_CHAIN_ELEMENT* pIL2 = pIL + i;
                            if (pIL2->cbSize <= 0)
                            {
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Assert("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString());
                                }

                                Debug.Fail("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString());
                            }

                            if (pIL2->cbSize > 0)
                            {
                                uint size = pIL2->cbSize;
                                byte* ptr = (byte*)(pIL2->pCertContext);
                                byte[] x = new byte[size];
                                for (int j = 0; j < size; j++)
                                {
                                    x[j] = *(ptr + j);
                                }

                                X500DistinguishedName x500DistinguishedName = new X500DistinguishedName(x);
                                issuers[i] = x500DistinguishedName.Name;
                                if (GlobalLog.IsEnabled)
                                {
                                    GlobalLog.Print("SecureChannel#" + LoggingHash.HashString(securityContext) + "::GetIssuers() IssuerListEx[" + i + "]:" + issuers[i]);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                if (issuerList.aIssuers != null)
                {
                    issuerList.aIssuers.Dispose();
                }
            }

            return issuers;
        }
Ejemplo n.º 29
0
		private void Empty (X500DistinguishedName dn)
		{
			Assert.AreEqual (String.Empty, dn.Name, "Name");

			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.None), "Decode(None)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.Reversed), "Decode(Reversed)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.UseSemicolons), "Decode(UseSemicolons)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.DoNotUsePlusSign), "Decode(DoNotUsePlusSign)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.DoNotUseQuotes), "Decode(DoNotUseQuotes)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.UseCommas), "Decode(UseCommas)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.UseNewLines), "Decode(UseNewLines)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.UseUTF8Encoding), "Decode(UseUTF8Encoding)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.UseT61Encoding), "Decode(UseT61Encoding)");
			Assert.AreEqual (String.Empty, dn.Decode (X500DistinguishedNameFlags.ForceUTF8Encoding), "Decode(ForceUTF8Encoding)");

			Assert.AreEqual (String.Empty, dn.Format (true), "Format(true)");
			Assert.AreEqual (String.Empty, dn.Format (false), "Format(false)");
		}
 public X509Identity(X500DistinguishedName x500DistinguishedName)
     : base(X509, X509)
 {
     _x500DistinguishedName = x500DistinguishedName;
 }
        private byte[] Build(
            X500DistinguishedName issuerName,
            X509SignatureGenerator generator,
            BigInteger crlNumber,
            DateTimeOffset nextUpdate,
            DateTimeOffset thisUpdate,
            HashAlgorithmName hashAlgorithm,
            X509AuthorityKeyIdentifierExtension authorityKeyIdentifier)
        {
            ArgumentNullException.ThrowIfNull(issuerName);
            ArgumentNullException.ThrowIfNull(generator);

            if (crlNumber < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(crlNumber), SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (nextUpdate <= thisUpdate)
            {
                throw new ArgumentException(SR.Cryptography_CRLBuilder_DatesReversed);
            }

            ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm));
            ArgumentNullException.ThrowIfNull(authorityKeyIdentifier);

            byte[] signatureAlgId = generator.GetSignatureAlgorithmIdentifier(hashAlgorithm);

            {
                AlgorithmIdentifierAsn signatureAlgorithmAsn;

                // Deserialization also does validation of the value (except for Parameters,
                // which have to be validated separately).
                signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgId, AsnEncodingRules.DER);

                if (signatureAlgorithmAsn.Parameters.HasValue)
                {
                    Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.GetValueOrDefault().Span);
                }
            }

            AsnWriter writer = (_writer ??= new AsnWriter(AsnEncodingRules.DER));

            writer.Reset();

            // TBSCertList
            using (writer.PushSequence())
            {
                // version v2(1)
                writer.WriteInteger(1);

                // signature (AlgorithmIdentifier)
                writer.WriteEncodedValue(signatureAlgId);

                // issuer
                writer.WriteEncodedValue(issuerName.RawData);

                // thisUpdate
                WriteX509Time(writer, thisUpdate);

                // nextUpdate
                WriteX509Time(writer, nextUpdate);

                // revokedCertificates (don't write down if empty)
                if (_revoked.Count > 0)
                {
                    // SEQUENCE OF
                    using (writer.PushSequence())
                    {
                        foreach (RevokedCertificate revoked in _revoked)
                        {
                            // Anonymous CRL Entry type
                            using (writer.PushSequence())
                            {
                                writer.WriteInteger(revoked.Serial);
                                WriteX509Time(writer, revoked.RevocationTime);

                                if (revoked.Extensions is not null)
                                {
                                    writer.WriteEncodedValue(revoked.Extensions);
                                }
                            }
                        }
                    }
                }

                // extensions [0] EXPLICIT Extensions
                using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)))
                {
                    // Extensions (SEQUENCE OF)
                    using (writer.PushSequence())
                    {
                        // Authority Key Identifier Extension
                        using (writer.PushSequence())
                        {
                            writer.WriteObjectIdentifier(authorityKeyIdentifier.Oid !.Value !);

                            if (authorityKeyIdentifier.Critical)
                            {
                                writer.WriteBoolean(true);
                            }

                            byte[] encodedAkid = authorityKeyIdentifier.RawData;
                            Helpers.ValidateDer(encodedAkid);
                            writer.WriteOctetString(encodedAkid);
                        }

                        // CRL Number Extension
                        using (writer.PushSequence())
                        {
                            writer.WriteObjectIdentifier(Oids.CrlNumber);

                            using (writer.PushOctetString())
                            {
                                writer.WriteInteger(crlNumber);
                            }
                        }
                    }
                }
            }

            byte[] tbsCertList = writer.Encode();
            writer.Reset();

            byte[] signature = generator.SignData(tbsCertList, hashAlgorithm);

            // CertificateList
            using (writer.PushSequence())
            {
                writer.WriteEncodedValue(tbsCertList);
                writer.WriteEncodedValue(signatureAlgId);
                writer.WriteBitString(signature);
            }

            byte[] crl = writer.Encode();
            return(crl);
        }
Ejemplo n.º 32
0
		public override void Reset () 
		{
			_cert = null;
			_archived = false;
			_extensions = null;
			_name = String.Empty;
			_serial = null;
			_publicKey = null;
			issuer_name = null;
			subject_name = null;
			signature_algorithm = null;
			base.Reset ();
		}
Ejemplo n.º 33
0
        internal unsafe SubjectIdentifier (CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) {
            // If serial number is 0, then it is the special SKI encoding or NoSignature
            bool isSKIorHashOnly = true;
            byte * pb = (byte *) serialNumber.pbData;
            for (uint i = 0; i < serialNumber.cbData; i++) {
                if (*pb++ != (byte) 0) {
                    isSKIorHashOnly = false;
                    break;
                }
            }

            if (isSKIorHashOnly) {
                byte[] issuerBytes = new byte[issuer.cbData];
                Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length);
                X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes);
                if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) {
                    Reset(SubjectIdentifierType.NoSignature, null);
                    return;
                }
            }

            if (isSKIorHashOnly) {
                // Decode disguised SKI in issuer field (See WinCrypt.h for more info).  Note that some certificates may contain
                // an all-zero serial number but not be encoded with an szOID_KEYID_RDN.  In order to allow use of signatures created
                // using these certificates, we will first try to find the szOID_KEYID_RDN, but if it does not exist, fall back to just
                // decoding the incoming issuer and serial number.
                m_type = SubjectIdentifierType.SubjectKeyIdentifier;
                m_value = String.Empty;

                uint cbCertNameInfo = 0;
                SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle;

                if (CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME),
                                      issuer.pbData,
                                      issuer.cbData,
                                      out pbCertNameInfo,
                                      out cbCertNameInfo)) {
                    using (pbCertNameInfo) {
                        checked {
                            CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO) Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO));
                            for (uint i = 0; i < certNameInfo.cRDN; i++) {
                                CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN) Marshal.PtrToStructure(new IntPtr((long) certNameInfo.rgRDN + (long) (i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN));

                                for (uint j = 0; j < certRdn.cRDNAttr; j++)
                                {
                                    CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR)Marshal.PtrToStructure(new IntPtr((long)certRdn.rgRDNAttr + (long)(j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR));

                                    if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING)
                                        {
                                            byte[] ski = new byte[certRdnAttr.Value.cbData];
                                            Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length);
                                            Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski));
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial;
            IssuerAndSerial.Issuer = issuer;
            IssuerAndSerial.SerialNumber = serialNumber;
            X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial);
            Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial);
        }
Ejemplo n.º 34
0
		public X500DistinguishedName (X500DistinguishedName distinguishedName)
		{
			if (distinguishedName == null)
				throw new ArgumentNullException ("distinguishedName");

			Oid = new Oid ();
			RawData = distinguishedName.RawData;
			name = distinguishedName.name;
		}
Ejemplo n.º 35
0
        private string FormatDistinguishedName(X500DistinguishedName dn)
        {
            var subjectName = dn.Name;
            if (subjectName.Contains("\""))
            {
                bool insideQuotes = false;
                string subjectName2 = string.Empty;
                for (int i = 0; i < subjectName.Length; i++)
                {
                    if (subjectName[i] == '"') insideQuotes = !insideQuotes;
                    if ((subjectName[i] == ',') && insideQuotes)
                        subjectName2 += '#';
                    else subjectName2 += subjectName[i];
                }

                subjectName = subjectName2;
            }

            var parts = subjectName.Split(',');
            var part = string.Empty;

            if (parts.Length == 0) part = dn.Name;
            else part = parts[0];

            part = part.Replace('#', ',');
            part = part.Replace("\"", string.Empty);

            int index = part.IndexOf('=');
            if (index != -1) part = part.Substring(index + 1);

            return part;
        }
Ejemplo n.º 36
0
 public X500DistinguishedName(X500DistinguishedName distinguishedName) : base((AsnEncodedData)distinguishedName)
 {
     m_distinguishedName = distinguishedName.Name;
 }
            public X500DistinguishedNameClaimSet(X500DistinguishedName x500DistinguishedName)
            {
                if (x500DistinguishedName == null)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("x500DistinguishedName");

                _identity = new X509Identity(x500DistinguishedName);
                List<Claim> claims = new List<Claim>(2);
                claims.Add(new Claim(ClaimTypes.X500DistinguishedName, x500DistinguishedName, Rights.Identity));
                claims.Add(Claim.CreateX500DistinguishedNameClaim(x500DistinguishedName));
                Initialize(ClaimSet.Anonymous, claims);
            }
Ejemplo n.º 38
0
        /// <summary>
        /// Create a new certificate
        /// </summary>
        /// <param name="issuer">Issuer certificate, if null then self-sign</param>
        /// <param name="subjectName">Subject name</param>
        /// <param name="serialNumber">Serial number of certificate, if null then will generate a new one</param>
        /// <param name="signature">If true create an AT_SIGNATURE key, otherwise AT_EXCHANGE</param>
        /// <param name="keySize">Size of RSA key</param>
        /// <param name="notBefore">Start date of certificate</param>
        /// <param name="notAfter">End date of certificate</param>
        /// <param name="extensions">Array of extensions, if null then no extensions</param>
        /// <param name="hashAlgorithm">Specify the signature hash algorithm</param>
        /// <returns>The created X509 certificate</returns>
        public SystemX509.X509Certificate2 CreateCert(SystemX509.X509Certificate2 issuer, SystemX509.X500DistinguishedName subjectName,
                                                      byte[] serialNumber, bool signature, int keySize, CertificateHashAlgorithm hashAlgorithm, DateTime notBefore,
                                                      DateTime notAfter, SystemX509.X509ExtensionCollection extensions)
        {
            X509V3CertificateGenerator builder    = new X509V3CertificateGenerator();
            AsymmetricAlgorithm        subjectKey = CreateRSAKey(keySize, signature);
            AsymmetricAlgorithm        signKey    = issuer == null ? subjectKey : issuer.PrivateKey;

            if (signKey == null)
            {
                throw new ArgumentException(Properties.Resources.CreateCert_NoPrivateKey);
            }

            AsymmetricCipherKeyPair bcSubjectKey = GetRsaKeyPair((RSACryptoServiceProvider)subjectKey);
            AsymmetricCipherKeyPair bcSignKey    = GetRsaKeyPair((RSACryptoServiceProvider)signKey);

            X509Name issuerNameObj = issuer == null?X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData))
                                         : X509Name.GetInstance(Asn1Object.FromByteArray(issuer.SubjectName.RawData));

            X509Name subjectNameObj = X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData));

            BigInteger subjectSerial = new BigInteger(1, serialNumber != null ? serialNumber : Guid.NewGuid().ToByteArray());
            BigInteger issuerSerial  = issuer == null ? subjectSerial : new BigInteger(1, issuer.GetSerialNumber());

            builder.SetIssuerDN(issuerNameObj);
            builder.SetSubjectDN(subjectNameObj);
            builder.SetSerialNumber(subjectSerial);
            builder.SetSignatureAlgorithm(HashAlgorithmToName(hashAlgorithm));
            builder.SetNotBefore(notBefore.ToUniversalTime());
            builder.SetNotAfter(notAfter.ToUniversalTime());
            builder.SetPublicKey(bcSubjectKey.Public);

            SubjectPublicKeyInfo   info         = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSignKey.Public);
            AuthorityKeyIdentifier authKeyId    = new AuthorityKeyIdentifier(info, new GeneralNames(new GeneralName(issuerNameObj)), issuerSerial);
            SubjectKeyIdentifier   subjectKeyid = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSubjectKey.Public));

            builder.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, true, authKeyId);
            builder.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, true, subjectKeyid);

            if (extensions != null)
            {
                foreach (SystemX509.X509Extension ext in extensions)
                {
                    if (!ext.Oid.Value.Equals(X509Extensions.AuthorityKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(X509Extensions.SubjectKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(szOID_AUTHORITY_KEY_IDENTIFIER2))
                    {
                        Asn1InputStream istm = new Org.BouncyCastle.Asn1.Asn1InputStream(ext.RawData);
                        Asn1Object      obj  = istm.ReadObject();
                        builder.AddExtension(ext.Oid.Value, ext.Critical, obj);
                    }
                }
            }

            X509Certificate cert = builder.Generate(bcSignKey.Private);

            SystemX509.X509Certificate2 ret = new SystemX509.X509Certificate2(cert.GetEncoded(), (string)null, SystemX509.X509KeyStorageFlags.Exportable);

            ret.PrivateKey = subjectKey;

            return(ret);
        }
Ejemplo n.º 39
0
        public static Claim CreateX500DistinguishedNameClaim(X500DistinguishedName x500DistinguishedName)
        {
            if (x500DistinguishedName == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("x500DistinguishedName");

            return new Claim(ClaimTypes.X500DistinguishedName, x500DistinguishedName, Rights.PossessProperty, ClaimComparer.X500DistinguishedName);
        }
Ejemplo n.º 40
0
		public void Constructor_String ()
		{
			X500DistinguishedName dn = new X500DistinguishedName ("OU=Secure Server Certification Authority, O=\"RSA Data Security, Inc.\", C=US");
			Assert.IsNotNull (dn.Oid, "Oid");
			Assert.IsNull (dn.Oid.Value, "Oid.Value");
			Assert.IsNull (dn.Oid.FriendlyName, "Oid.FriendlyName");
			RsaIssuer (dn);
		}
        ///// <summary>
        ///// Create a new certificate
        ///// </summary>
        ///// <param name="issuer">Issuer certificate, if null then self-sign</param>
        ///// <param name="subjectName">Subject name</param>
        ///// <param name="serialNumber">Serial number of certificate, if null then will generate a new one</param>
        ///// <param name="keySize">Size of RSA key</param>
        ///// <param name="notBefore">Start date of certificate</param>
        ///// <param name="notAfter">End date of certificate</param>
        ///// <param name="extensions">Array of extensions, if null then no extensions</param>
        ///// <param name="hashAlgorithm">Specify the signature hash algorithm</param>
        ///// <returns>The created X509 certificate</returns>
        public static SystemX509.X509Certificate2 CreateCert(SystemX509.X509Certificate2 issuer, SystemX509.X500DistinguishedName subjectName,
                                                             byte[] serialNumber, int keySize, CertificateHashAlgorithm hashAlgorithm, DateTime notBefore,
                                                             DateTime notAfter, SystemX509.X509ExtensionCollection extensions)
        {
            SecureRandom random = new SecureRandom();
            X509V3CertificateGenerator builder      = new X509V3CertificateGenerator();
            AsymmetricCipherKeyPair    bcSubjectKey = CreateRSAKey(keySize, random);
            AsymmetricCipherKeyPair    bcSignKey    = issuer == null ? bcSubjectKey : issuer.GetBCPrivateKey();

            if (bcSignKey == null)
            {
                throw new ArgumentException("issuer");
            }

            X509Name issuerNameObj = issuer == null?X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData))
                                         : X509Name.GetInstance(Asn1Object.FromByteArray(issuer.SubjectName.RawData));

            X509Name subjectNameObj = X509Name.GetInstance(Asn1Object.FromByteArray(subjectName.RawData));

            BigInteger subjectSerial = new BigInteger(1, serialNumber != null ? serialNumber : Guid.NewGuid().ToByteArray());
            BigInteger issuerSerial  = issuer == null ? subjectSerial : new BigInteger(1, issuer.GetSerialNumber());

            builder.SetIssuerDN(issuerNameObj);
            builder.SetSubjectDN(subjectNameObj);
            builder.SetSerialNumber(subjectSerial);
            builder.SetNotBefore(notBefore.ToUniversalTime());
            builder.SetNotAfter(notAfter.ToUniversalTime());
            builder.SetPublicKey(bcSubjectKey.Public);

            SubjectPublicKeyInfo   info         = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSignKey.Public);
            AuthorityKeyIdentifier authKeyId    = new AuthorityKeyIdentifier(info, new GeneralNames(new GeneralName(issuerNameObj)), issuerSerial);
            SubjectKeyIdentifier   subjectKeyid = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(bcSubjectKey.Public));

            builder.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, true, authKeyId);
            builder.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, true, subjectKeyid);

            if (extensions != null)
            {
                foreach (SystemX509.X509Extension ext in extensions)
                {
                    if (!ext.Oid.Value.Equals(X509Extensions.AuthorityKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(X509Extensions.SubjectKeyIdentifier.Id) &&
                        !ext.Oid.Value.Equals(szOID_AUTHORITY_KEY_IDENTIFIER2))
                    {
                        Asn1InputStream istm = new Asn1InputStream(ext.RawData);
                        Asn1Object      obj  = istm.ReadObject();
                        builder.AddExtension(ext.Oid.Value, ext.Critical, obj);
                    }
                }
            }

            X509Certificate cert = builder.Generate(CreateSignatureFactory(hashAlgorithm, bcSignKey, random));

            Pkcs12StoreBuilder   pkcs  = new Pkcs12StoreBuilder();
            Pkcs12Store          store = pkcs.Build();
            X509CertificateEntry entry = new X509CertificateEntry(cert);

            store.SetCertificateEntry("main", entry);

            AsymmetricKeyEntry key_entry = new AsymmetricKeyEntry(bcSubjectKey.Private);

            store.SetKeyEntry("main", key_entry, new[] { entry });
            MemoryStream stm = new MemoryStream();

            store.Save(stm, new char[0], new SecureRandom());
            return(new SystemX509.X509Certificate2(stm.ToArray(), String.Empty, SystemX509.X509KeyStorageFlags.Exportable));
        }
Ejemplo n.º 42
0
		public void Constructor_String_Empty_Flags ()
		{
			X500DistinguishedName dn = new X500DistinguishedName (String.Empty, X500DistinguishedNameFlags.None);
			Assert.AreEqual (2, dn.RawData.Length, "RawData.Length");
			Assert.AreEqual ("30-00", BitConverter.ToString (dn.RawData), "RawData");
			Empty (dn);
		}
Ejemplo n.º 43
0
		// of all X500DistinguishedNameFlags flags nothing can do a "correct" comparison :|
		internal static bool AreEqual (X500DistinguishedName name1, X500DistinguishedName name2)
		{
			if (name1 == null)
				return (name2 == null);
			if (name2 == null)
				return false;

			if (name1.canonEncoding != null && name2.canonEncoding != null) {
				if (name1.canonEncoding.Length != name2.canonEncoding.Length)
					return false;
				for (int i = 0; i < name1.canonEncoding.Length; i++) {
					if (name1.canonEncoding[i] != name2.canonEncoding[i])
						return false;
				}
				return true;
			}

			X500DistinguishedNameFlags flags = X500DistinguishedNameFlags.UseNewLines | X500DistinguishedNameFlags.DoNotUseQuotes;
			string[] split = new string[] { Environment.NewLine };
			string[] parts1 = name1.Decode (flags).Split (split, StringSplitOptions.RemoveEmptyEntries);
			string[] parts2 = name2.Decode (flags).Split (split, StringSplitOptions.RemoveEmptyEntries);
			if (parts1.Length != parts2.Length)
				return false;

			for (int i = 0; i < parts1.Length; i++) {
				if (Canonize (parts1[i]) != Canonize (parts2[i]))
					return false;
			}
			return true;
		}
Ejemplo n.º 44
0
		public void Constructor_String_Flags_None ()
		{
			X500DistinguishedName dn = new X500DistinguishedName (rname, X500DistinguishedNameFlags.None);
			// can't call RsaIssuer because Name is reversed from None in those cases
			// i.e. X500DistinguishedName (string) != X500DistinguishedName (string, X500DistinguishedNameFlags)
			Assert.AreEqual (rname, dn.Name, "Name");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.None), "Decode(None)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.Reversed), "Decode(Reversed)");
			Assert.AreEqual ("C=US; O=\"RSA Data Security, Inc.\"; OU=Secure Server Certification Authority", dn.Decode (X500DistinguishedNameFlags.UseSemicolons), "Decode(UseSemicolons)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.DoNotUsePlusSign), "Decode(DoNotUsePlusSign)");
			Assert.AreEqual ("C=US, O=RSA Data Security, Inc., OU=Secure Server Certification Authority", dn.Decode (X500DistinguishedNameFlags.DoNotUseQuotes), "Decode(DoNotUseQuotes)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.UseCommas), "Decode(UseCommas)");
			string newline = String.Format ("C=US{0}O=\"RSA Data Security, Inc.\"{0}OU=Secure Server Certification Authority", Environment.NewLine);
			Assert.AreEqual (newline, dn.Decode (X500DistinguishedNameFlags.UseNewLines), "Decode(UseNewLines)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.UseUTF8Encoding), "Decode(UseUTF8Encoding)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.UseT61Encoding), "Decode(UseT61Encoding)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.ForceUTF8Encoding), "Decode(ForceUTF8Encoding)");
		}
Ejemplo n.º 45
0
		// CTL == Certificate Trust List / NOT SUPPORTED
		// TODO - check for X509ChainStatusFlags.CtlNotTimeValid
		// TODO - check for X509ChainStatusFlags.CtlNotSignatureValid
		// TODO - check for X509ChainStatusFlags.CtlNotValidForUsage

		private void PrepareForNextCertificate (int n) 
		{
			X509ChainElement element = elements [n];
			X509Certificate2 certificate = element.Certificate;

			// TODO 6.1.4.a-b

			// 6.1.4.c
			working_issuer_name = certificate.SubjectName;
			// 6.1.4.d-e - our key includes both the public key and it's parameters
			working_public_key = certificate.PublicKey.Key;
			// 6.1.4.f
//			working_public_key_algorithm = certificate.PublicKey.Oid.Value;

			// TODO 6.1.4.g-j

			// 6.1.4.k - Verify that the certificate is a CA certificate
			X509BasicConstraintsExtension bce = (certificate.Extensions["2.5.29.19"] as X509BasicConstraintsExtension);
			if (bce != null) {
				if (!bce.CertificateAuthority) {
					element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
				}
			} else if (certificate.Version >= 3) {
				// recent (v3+) CA certificates must include BCE
				element.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
			}

			// 6.1.4.l - if the certificate isn't self-issued...
			if (!IsSelfIssued (certificate)) {
				// ... verify that max_path_length > 0
				if (max_path_length > 0) {
					max_path_length--;
				} else {
					// to match MS the reported status must be against the certificate 
					// with the BCE and not where the path is too long. It also means
					// that this condition has to be reported only once
					if (bce_restriction != null) {
						bce_restriction.StatusFlags |= X509ChainStatusFlags.InvalidBasicConstraints;
					}
				}
			}

			// 6.1.4.m - if pathLengthConstraint is present...
			if ((bce != null) && (bce.HasPathLengthConstraint)) {
				// ... and is less that max_path_length, set max_path_length to it's value
				if (bce.PathLengthConstraint < max_path_length) {
					max_path_length = bce.PathLengthConstraint;
					bce_restriction = element;
				}
			}

			// 6.1.4.n - if key usage extension is present...
			X509KeyUsageExtension kue = (certificate.Extensions["2.5.29.15"] as X509KeyUsageExtension);
			if (kue != null) {
				// ... verify keyCertSign is set
				X509KeyUsageFlags success = X509KeyUsageFlags.KeyCertSign;
				if ((kue.KeyUsages & success) != success)
					element.StatusFlags |= X509ChainStatusFlags.NotValidForUsage;
			}

			// 6.1.4.o - recognize and process other critical extension present in the certificate
			ProcessCertificateExtensions (element);
		}
Ejemplo n.º 46
0
		public void Constructor_String_Flags_Reversed ()
		{
			X500DistinguishedName dn = new X500DistinguishedName (name, X500DistinguishedNameFlags.None);
			// can't call RsaIssuer because Name is reversed from None in those cases
			Assert.AreEqual (name, dn.Name, "Name");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.None), "Decode(None)");
			Assert.AreEqual (rname, dn.Decode (X500DistinguishedNameFlags.Reversed), "Decode(Reversed)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.DoNotUsePlusSign), "Decode(DoNotUsePlusSign)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.UseCommas), "Decode(UseCommas)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.UseUTF8Encoding), "Decode(UseUTF8Encoding)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.UseT61Encoding), "Decode(UseT61Encoding)");
			Assert.AreEqual (name, dn.Decode (X500DistinguishedNameFlags.ForceUTF8Encoding), "Decode(ForceUTF8Encoding)");
		}