public static void TestDecodeFormats(X500DistinguishedNameFlags format) { // The Issuer field from the Microsoft.com test cert. byte[] encoding = ( "3077310B3009060355040613025553311D301B060355040A131453796D616E74" + "656320436F72706F726174696F6E311F301D060355040B131653796D616E7465" + "63205472757374204E6574776F726B312830260603550403131F53796D616E74" + "656320436C61737320332045562053534C204341202D204733").HexToByteArray(); X500DistinguishedName name = new X500DistinguishedName(encoding); string delimiter; switch (format) { case X500DistinguishedNameFlags.UseCommas: delimiter = ", "; break; case X500DistinguishedNameFlags.UseSemicolons: delimiter = "; "; break; case X500DistinguishedNameFlags.UseNewLines: delimiter = Environment.NewLine; break; default: throw new InvalidOperationException("No handler for format: " + format); } string expected = string.Format( "C=US{0}O=Symantec Corporation{0}OU=Symantec Trust Network{0}CN=Symantec Class 3 EV SSL CA - G3", delimiter); string actual = name.Decode(format); Assert.Equal(expected, actual); }
public static void NoQuoteWhitespaceAfter(string expectedQuoted, string hexEncoded) { string expected = expectedQuoted.Replace("\"", ""); byte[] encoded = hexEncoded.HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal(expected, dn.Decode(X500DistinguishedNameFlags.DoNotUseQuotes)); }
public static void PrintUnknownOidRdn() { byte[] encoded = ( "30183116301406052901020203130B496E76616C6964204F6964").HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal("OID.1.1.1.2.2.3=Invalid Oid", dn.Decode(X500DistinguishedNameFlags.None)); }
public static void PrintInvalidEncoding() { // One byte has been removed from the payload here. Since DER is length-prepended // this will run out of data too soon, and report as invalid. byte[] encoded = "3017311530130603550403130C436F6D6D6F6E204E616D65".HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal("", dn.Decode(X500DistinguishedNameFlags.None)); }
public static void TestDecode() { byte[] encoding = "300e310c300a06035504031303466f6f".HexToByteArray(); X500DistinguishedName n = new X500DistinguishedName(encoding); String s = n.Name; Assert.Equal("CN=Foo", s); byte[] rawData = n.RawData; Assert.Equal(encoding, rawData); }
public static void TestFormat() { byte[] encoding = "300e310c300a06035504031303466f6f".HexToByteArray(); String s; X500DistinguishedName n = new X500DistinguishedName(encoding); s = n.Format(multiLine: false); Assert.Equal("CN=Foo", s); s = n.Format(multiLine: true); Assert.Equal("CN=Foo\r\n", s); }
public static void PrintMultiComponentRdn() { byte[] encoded = ( "30223120300C060355040313054A616D65733010060355040A13094D6963726F" + "736F6674").HexToByteArray(); const string expected = "CN=James + O=Microsoft"; X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal(expected, dn.Decode(X500DistinguishedNameFlags.None)); // It should not change ordering when reversed, since the two are one unit. Assert.Equal(expected, dn.Decode(X500DistinguishedNameFlags.Reversed)); }
public static void PrintComplexReversed() { byte[] encoded = MicrosoftDotComSubject.HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); const string expected = "CN=www.microsoft.com, OU=MSCOM, O=Microsoft Corporation, STREET=1 Microsoft Way, " + "L=Redmond, S=Washington, PostalCode=98052, C=US, SERIALNUMBER=600413485, "; // Windows 8.1 would continue the string with some unknown OIDs, but OpenSSL 1.0.1 can decode // at least businessCategory (2.5.4.15), and other Windows versions may do so in the future. // "OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Washington, " + // "OID.1.3.6.1.4.1.311.60.2.1.3=US"; Assert.StartsWith(expected, dn.Decode(X500DistinguishedNameFlags.Reversed), StringComparison.Ordinal); }
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); EnsureCertData(); if (nameType == X509NameType.SimpleName) { X500DistinguishedName name = forIssuer ? _certData.Issuer : _certData.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 _certData.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 ? _certData.Issuer : _certData.Subject; foreach (var kvp in ReadReverseRdns(name)) { if (kvp.Key == expectedKey) { return(kvp.Value); } } } } return(""); }
public X509Identity(X500DistinguishedName x500DistinguishedName) : base(X509, X509) { _x500DistinguishedName = x500DistinguishedName; }
/// <summary>建立自签名证书</summary> /// <param name="distName"></param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="password"></param> /// <returns></returns> public static byte[] CreateSelfSignCertificatePfx(X500DistinguishedName distName, DateTime startTime, DateTime endTime, SecureString password) { byte[] pfxData; SystemTime startSystemTime = ToSystemTime(startTime); SystemTime endSystemTime = ToSystemTime(endTime); string containerName = Guid.NewGuid().ToString(); GCHandle dataHandle = new GCHandle(); IntPtr providerContext = IntPtr.Zero; IntPtr cryptKey = IntPtr.Zero; IntPtr certContext = IntPtr.Zero; IntPtr certStore = IntPtr.Zero; IntPtr storeCertContext = IntPtr.Zero; IntPtr passwordPtr = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { Check(NativeMethods.CryptAcquireContextW( out providerContext, containerName, null, 1, // PROV_RSA_FULL 8)); // CRYPT_NEWKEYSET Check(NativeMethods.CryptGenKey( providerContext, 1, // AT_KEYEXCHANGE 1, // CRYPT_EXPORTABLE out cryptKey)); byte[] nameData = distName.RawData; dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned); CryptoApiBlob nameBlob = new CryptoApiBlob( nameData.Length, dataHandle.AddrOfPinnedObject()); CryptKeyProviderInformation kpi = new CryptKeyProviderInformation(); kpi.ContainerName = containerName; kpi.ProviderType = 1; // PROV_RSA_FULL kpi.KeySpec = 1; // AT_KEYEXCHANGE certContext = NativeMethods.CertCreateSelfSignCertificate( providerContext, ref nameBlob, 0, ref kpi, IntPtr.Zero, // default = SHA1RSA ref startSystemTime, ref endSystemTime, IntPtr.Zero); Check(certContext != IntPtr.Zero); dataHandle.Free(); certStore = NativeMethods.CertOpenStore( "Memory", // sz_CERT_STORE_PROV_MEMORY 0, IntPtr.Zero, 0x2000, // CERT_STORE_CREATE_NEW_FLAG IntPtr.Zero); Check(certStore != IntPtr.Zero); Check(NativeMethods.CertAddCertificateContextToStore( certStore, certContext, 1, // CERT_STORE_ADD_NEW out storeCertContext)); NativeMethods.CertSetCertificateContextProperty( storeCertContext, 2, // CERT_KEY_PROV_INFO_PROP_ID 0, ref kpi); if (password != null) { passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password); } CryptoApiBlob pfxBlob = new CryptoApiBlob(); Check(NativeMethods.PFXExportCertStoreEx( certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY pfxData = new byte[pfxBlob.DataLength]; dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned); pfxBlob.Data = dataHandle.AddrOfPinnedObject(); Check(NativeMethods.PFXExportCertStoreEx( certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY dataHandle.Free(); } finally { if (passwordPtr != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); } if (dataHandle.IsAllocated) { dataHandle.Free(); } if (certContext != IntPtr.Zero) { NativeMethods.CertFreeCertificateContext(certContext); } if (storeCertContext != IntPtr.Zero) { NativeMethods.CertFreeCertificateContext(storeCertContext); } if (certStore != IntPtr.Zero) { NativeMethods.CertCloseStore(certStore, 0); } if (cryptKey != IntPtr.Zero) { NativeMethods.CryptDestroyKey(cryptKey); } if (providerContext != IntPtr.Zero) { NativeMethods.CryptReleaseContext(providerContext, 0); NativeMethods.CryptAcquireContextW( out providerContext, containerName, null, 1, // PROV_RSA_FULL 0x10); // CRYPT_DELETEKEYSET } } return(pfxData); }
internal bool verify(NativeConnectionInfo info, string desc) { List <List <List <RFC2253.RDNPair> > > reject = new List <List <List <RFC2253.RDNPair> > >(), accept = new List <List <List <RFC2253.RDNPair> > >(); if (rejectAll_.Count != 0) { reject.Add(rejectAll_); } if (info.incoming) { if (rejectAllServer_.Count != 0) { reject.Add(rejectAllServer_); } if (info.adapterName.Length > 0) { List <List <RFC2253.RDNPair> > p = null; if (rejectServer_.TryGetValue(info.adapterName, out p)) { reject.Add(p); } } } else { if (rejectClient_.Count != 0) { reject.Add(rejectClient_); } } if (acceptAll_.Count != 0) { accept.Add(acceptAll_); } if (info.incoming) { if (acceptAllServer_.Count != 0) { accept.Add(acceptAllServer_); } if (info.adapterName.Length > 0) { List <List <RFC2253.RDNPair> > p = null; if (acceptServer_.TryGetValue(info.adapterName, out p)) { accept.Add(p); } } } else { if (acceptClient_.Count != 0) { accept.Add(acceptClient_); } } // // If there is nothing to match against, then we accept the cert. // if (reject.Count == 0 && accept.Count == 0) { return(true); } // // If there is no certificate then we match false. // if (info.nativeCerts != null && info.nativeCerts.Length > 0) { X500DistinguishedName subjectDN = info.nativeCerts[0].SubjectName; string subjectName = subjectDN.Name; Debug.Assert(subjectName != null); try { // // Decompose the subject DN into the RDNs. // if (traceLevel_ > 0) { if (info.incoming) { communicator_.getLogger().trace("Security", "trust manager evaluating client:\n" + "subject = " + subjectName + "\n" + "adapter = " + info.adapterName + "\n" + desc); } else { communicator_.getLogger().trace("Security", "trust manager evaluating server:\n" + "subject = " + subjectName + "\n" + desc); } } List <RFC2253.RDNPair> dn = RFC2253.parseStrict(subjectName); // // Unescape the DN. Note that this isn't done in // the parser in order to keep the various RFC2253 // implementations as close as possible. // for (int i = 0; i < dn.Count; ++i) { RFC2253.RDNPair p = dn[i]; p.value = RFC2253.unescape(p.value); dn[i] = p; } // // Fail if we match anything in the reject set. // foreach (List <List <RFC2253.RDNPair> > matchSet in reject) { if (traceLevel_ > 0) { StringBuilder s = new StringBuilder("trust manager rejecting PDNs:\n"); stringify(matchSet, s); communicator_.getLogger().trace("Security", s.ToString()); } if (match(matchSet, dn)) { return(false); } } // // Succeed if we match anything in the accept set. // foreach (List <List <RFC2253.RDNPair> > matchSet in accept) { if (traceLevel_ > 0) { StringBuilder s = new StringBuilder("trust manager accepting PDNs:\n"); stringify(matchSet, s); communicator_.getLogger().trace("Security", s.ToString()); } if (match(matchSet, dn)) { return(true); } } } catch (RFC2253.ParseException e) { communicator_.getLogger().warning( "IceSSL: unable to parse certificate DN `" + subjectName + "'\nreason: " + e.reason); } // // At this point we accept the connection if there are no explicit accept rules. // return(accept.Count == 0); } return(false); }
/// <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="hashAlgorithm">The hash algorithm for the certificate</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> /// <returns>The created X509 certificate</returns> public static X509Certificate2 CreateCert(X509Certificate2 issuer, X500DistinguishedName subjectName, byte[] serialNumber, bool signature, int keySize, CertificateHashAlgorithm hashAlgorithm, DateTime notBefore, DateTime notAfter, X509ExtensionCollection extensions) { return(builder.CreateCert(issuer, subjectName, serialNumber, signature, keySize, hashAlgorithm, notBefore, notAfter, extensions)); }
public static void EncodeWithFlags(FlagControlledEncoderTestCase testCase) { X500DistinguishedName dn = new X500DistinguishedName(testCase.Input, testCase.Flags); ProcessTestCase(testCase, dn); }
public static void EncodeSingleRdn(SimpleEncoderTestCase testCase) { X500DistinguishedName dn = new X500DistinguishedName(testCase.Input, X500DistinguishedNameFlags.None); ProcessTestCase(testCase, dn); }
public static void CheckParserBoundaryCases(SimpleEncoderTestCase testCase) { X500DistinguishedName dn = new X500DistinguishedName(testCase.Input, X500DistinguishedNameFlags.None); ProcessTestCase(testCase, dn); }
/// <summary> /// Generates a new pairing record. /// </summary> /// <param name="devicePublicKey"> /// A <see cref="byte"/> array which represents the public key of the device with which to pair. /// </param> /// <param name="udid"> /// The UDID of the device. This will be included in the subjectName of the root certificate. /// This can be used to match the child certificates with the parent certificate based on the /// issuer name / subject name. /// This is not the default behavior of the canoncial implementation and should be needed on /// Windows for testing purposes only. /// </param> /// <param name="systemBuid"> /// A <see cref="string"/> which uniquely identifies the host. /// </param> /// <returns> /// A new <see cref="PairingRecord"/> which can be used to pair the host with the device. /// </returns> public virtual PairingRecord Generate(byte[] devicePublicKey, string udid, string systemBuid) { if (devicePublicKey == null) { throw new ArgumentNullException(nameof(devicePublicKey)); } if (systemBuid == null) { throw new ArgumentNullException(nameof(systemBuid)); } RSA rootKeyPair = RSA.Create(KeySize); RSA hostKeyPair = RSA.Create(KeySize); DateTimeOffset notBefore = DateTimeOffset.Now; DateTimeOffset notAfter = notBefore.AddDays(365 * 10); X500DistinguishedName caName = Name; if (udid != null) { caName = new X500DistinguishedName($"CN=Root Certification Authority,OU={udid}"); } var generator = new RSASha1Pkcs1SignatureGenerator(rootKeyPair); CertificateRequest rootRequest = new CertificateRequest( caName, rootKeyPair, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1); rootRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(certificateAuthority: true, hasPathLengthConstraint: false, pathLengthConstraint: -1, critical: true)); rootRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(rootRequest.PublicKey, critical: false)); var rootCert = rootRequest.Create( issuerName: caName, generator, notBefore: notBefore, notAfter: notAfter, serialNumber: new byte[] { 0 }); CertificateRequest hostRequest = new CertificateRequest( Name, hostKeyPair, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1); hostRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(certificateAuthority: false, hasPathLengthConstraint: false, pathLengthConstraint: -1, critical: true)); hostRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(hostRequest.PublicKey, critical: false)); hostRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, critical: true)); var hostCert = hostRequest.Create( issuerName: caName, generator, notBefore: notBefore, notAfter: notAfter, serialNumber: new byte[] { 0 }); var device = RSA.Create(); device.ImportFromPem(Encoding.UTF8.GetString(devicePublicKey)); var deviceRequest = new CertificateRequest( Name, device, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1); deviceRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(certificateAuthority: false, hasPathLengthConstraint: false, pathLengthConstraint: -1, critical: true)); deviceRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension("hash", critical: false)); deviceRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, critical: true)); var deviceCertificate = deviceRequest.Create( issuerName: caName, generator, notBefore: notBefore, notAfter: notAfter, serialNumber: new byte[] { 0 }); var hostId = Guid.NewGuid(); return(new PairingRecord() { DeviceCertificate = deviceCertificate, HostPrivateKey = hostKeyPair, HostCertificate = hostCert, RootPrivateKey = rootKeyPair, RootCertificate = rootCert, SystemBUID = systemBuid, HostId = hostId.ToString("D").ToUpperInvariant(), }); }
public X509Certificate2 CreateMutualAuthenticationX509(X500DistinguishedName fullSubject, DateTimeOffset validFrom, DateTimeOffset expires) { return CreateMutualAuthenticationX509(fullSubject.Format(false), validFrom, expires); }
internal static void MakeTestChain( ReadOnlySpan <RSA> keys, Span <X509Certificate2> certs, IEnumerable <X509Extension> endEntityExtensions, IEnumerable <X509Extension> intermediateExtensions, IEnumerable <X509Extension> rootExtensions) { if (keys.Length < 2) { throw new ArgumentException(nameof(keys)); } if (keys.Length != certs.Length) { throw new ArgumentException(nameof(certs)); } rootExtensions ??= new X509Extension[] { new X509BasicConstraintsExtension(true, false, 0, true), new X509KeyUsageExtension( X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.DigitalSignature, false) }; intermediateExtensions ??= new X509Extension[] { new X509BasicConstraintsExtension(true, false, 0, true), new X509KeyUsageExtension( X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.DigitalSignature, false) }; endEntityExtensions ??= new X509Extension[] { new X509BasicConstraintsExtension(false, false, 0, true), new X509KeyUsageExtension( X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation | X509KeyUsageFlags.KeyEncipherment, false) }; TimeSpan notBeforeInterval = TimeSpan.FromDays(30); TimeSpan notAfterInterval = TimeSpan.FromDays(90); DateTimeOffset eeStart = DateTimeOffset.UtcNow.AddDays(-7); DateTimeOffset eeEnd = eeStart.AddDays(45); byte[] serialBuf = new byte[16]; int rootIndex = keys.Length - 1; HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256; RSASignaturePadding signaturePadding = RSASignaturePadding.Pkcs1; CertificateRequest rootReq = new CertificateRequest( "CN=Test Root", keys[rootIndex], hashAlgorithm, signaturePadding); foreach (X509Extension extension in rootExtensions) { rootReq.CertificateExtensions.Add(extension); } X509SignatureGenerator lastGenerator = X509SignatureGenerator.CreateForRSA(keys[rootIndex], RSASignaturePadding.Pkcs1); X500DistinguishedName lastSubject = rootReq.SubjectName; certs[rootIndex] = rootReq.Create( lastSubject, lastGenerator, eeStart - (notBeforeInterval * rootIndex), eeEnd + (notAfterInterval * rootIndex), CreateSerial()); int presentationNumber = 0; for (int i = rootIndex - 1; i > 0; i--) { presentationNumber++; CertificateRequest intermediateReq = new CertificateRequest( $"CN=Intermediate Layer {presentationNumber}", keys[i], hashAlgorithm, signaturePadding); foreach (X509Extension extension in intermediateExtensions) { intermediateReq.CertificateExtensions.Add(extension); } certs[i] = intermediateReq.Create( lastSubject, lastGenerator, eeStart - (notBeforeInterval * i), eeEnd + (notAfterInterval * i), CreateSerial()); lastSubject = intermediateReq.SubjectName; lastGenerator = X509SignatureGenerator.CreateForRSA(keys[i], RSASignaturePadding.Pkcs1); } CertificateRequest eeReq = new CertificateRequest( "CN=End-Entity", keys[0], hashAlgorithm, signaturePadding); foreach (X509Extension extension in endEntityExtensions) { eeReq.CertificateExtensions.Add(extension); } certs[0] = eeReq.Create(lastSubject, lastGenerator, eeStart, eeEnd, CreateSerial()); }
// 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]; BCX509Certificate2 certificate = element.BCCertificate; // TODO 6.1.4.a-b // 6.1.4.c working_issuer_name = certificate.SubjectDN; // 6.1.4.d-e - our key includes both the public key and it's parameters working_public_key = certificate.GetPublicKey(); // 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 //BasicConstraints bce = (certificate.Extensions["2.5.29.19"] as BasicConstraints); BasicConstraints bce = BasicConstraints.GetInstance(certificate.CertificateStructure.TbsCertificate.Extensions.GetExtension(X509Extensions.BasicConstraints)); if (bce != null) { if (!bce.IsCA()) { 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.PathLenConstraint != null)) { // ... and is less that max_path_length, set max_path_length to it's value if (bce.PathLenConstraint.IntValue < max_path_length) { max_path_length = bce.PathLenConstraint.IntValue; bce_restriction = element; } } // 6.1.4.n - if key usage extension is present... //X509KeyUsage kue = (certificate.Extensions["2.5.29.15"] as X509KeyUsage); KeyUsage kue = KeyUsage.GetInstance(certificate.CertificateStructure.TbsCertificate.Extensions.GetExtension(X509Extensions.KeyUsage)); if (kue != null) { // ... verify keyCertSign is set //KeyUsage success = new KeyUsage(KeyUsage.KeyCertSign); //if ((kue.KeyUsages & success) != success) if ((kue.IntValue & KeyUsage.KeyCertSign) != KeyUsage.KeyCertSign) { element.StatusFlags |= X509ChainStatusFlags.NotValidForUsage; } } // 6.1.4.o - recognize and process other critical extension present in the certificate ProcessCertificateExtensions(element); }
internal CertificateData(byte[] rawData) { #if DEBUG try { #endif DerSequenceReader reader = new DerSequenceReader(rawData); DerSequenceReader tbsCertificate = reader.ReadSequence(); if (tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag0) { DerSequenceReader version = tbsCertificate.ReadSequence(); Version = version.ReadInteger(); } else if (tbsCertificate.PeekTag() != (byte)DerSequenceReader.DerTag.Integer) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } else { Version = 0; } if (Version < 0 || Version > 2) { throw new CryptographicException(); } SerialNumber = tbsCertificate.ReadIntegerBytes(); DerSequenceReader tbsSignature = tbsCertificate.ReadSequence(); TbsSignature.AlgorithmId = tbsSignature.ReadOidAsString(); TbsSignature.Parameters = tbsSignature.HasData ? tbsSignature.ReadNextEncodedValue() : Array.Empty <byte>(); if (tbsSignature.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Issuer = new X500DistinguishedName(tbsCertificate.ReadNextEncodedValue()); DerSequenceReader validity = tbsCertificate.ReadSequence(); NotBefore = validity.ReadX509Date(); NotAfter = validity.ReadX509Date(); if (validity.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Subject = new X500DistinguishedName(tbsCertificate.ReadNextEncodedValue()); SubjectPublicKeyInfo = tbsCertificate.ReadNextEncodedValue(); DerSequenceReader subjectPublicKeyInfo = new DerSequenceReader(SubjectPublicKeyInfo); DerSequenceReader subjectKeyAlgorithm = subjectPublicKeyInfo.ReadSequence(); PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadOidAsString(); PublicKeyAlgorithm.Parameters = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.ReadNextEncodedValue() : Array.Empty <byte>(); if (subjectKeyAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } PublicKey = subjectPublicKeyInfo.ReadBitString(); if (subjectPublicKeyInfo.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag1) { IssuerUniqueId = tbsCertificate.ReadBitString(); } else { IssuerUniqueId = null; } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag2) { SubjectUniqueId = tbsCertificate.ReadBitString(); } else { SubjectUniqueId = null; } Extensions = new List <X509Extension>(); if (Version > 1 && tbsCertificate.HasData && tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag3) { DerSequenceReader extensions = tbsCertificate.ReadSequence(); extensions = extensions.ReadSequence(); while (extensions.HasData) { DerSequenceReader extensionReader = extensions.ReadSequence(); string oid = extensionReader.ReadOidAsString(); bool critical = false; if (extensionReader.PeekTag() == (byte)DerSequenceReader.DerTag.Boolean) { critical = extensionReader.ReadBoolean(); } byte[] extensionData = extensionReader.ReadOctetString(); Extensions.Add(new X509Extension(oid, extensionData, critical)); if (extensionReader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } } if (tbsCertificate.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } DerSequenceReader signatureAlgorithm = reader.ReadSequence(); SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadOidAsString(); SignatureAlgorithm.Parameters = signatureAlgorithm.HasData ? signatureAlgorithm.ReadNextEncodedValue() : Array.Empty <byte>(); if (signatureAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } SignatureValue = reader.ReadBitString(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } RawData = rawData; #if DEBUG } catch (Exception e) { throw new CryptographicException( $"Error in reading certificate:{Environment.NewLine}{PemPrintCert(rawData)}", e); } #endif }
private static X509Certificate2Collection findCertificates(string prop, StoreLocation storeLocation, string name, string value) { // // Open the X509 certificate store. // X509Store store = null; try { try { store = new X509Store((StoreName)Enum.Parse(typeof(StoreName), name, true), storeLocation); } catch (ArgumentException) { store = new X509Store(name, storeLocation); } store.Open(OpenFlags.ReadOnly); } catch (Exception ex) { Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex); e.reason = "IceSSL: failure while opening store specified by " + prop; throw e; } // // Start with all of the certificates in the collection and filter as necessary. // // - If the value is "*", return all certificates. // - Otherwise, search using key:value pairs. The following keys are supported: // // Issuer // IssuerDN // Serial // Subject // SubjectDN // SubjectKeyId // Thumbprint // // A value must be enclosed in single or double quotes if it contains whitespace. // X509Certificate2Collection result = new X509Certificate2Collection(); result.AddRange(store.Certificates); try { if (value != "*") { if (value.IndexOf(':') == -1) { Ice.PluginInitializationException e = new Ice.PluginInitializationException(); e.reason = "IceSSL: no key in `" + value + "'"; throw e; } int start = 0; int pos; while ((pos = value.IndexOf(':', start)) != -1) { // // Parse the X509FindType. // string field = value.Substring(start, pos - start).Trim().ToUpperInvariant(); X509FindType findType; if (field.Equals("SUBJECT")) { findType = X509FindType.FindBySubjectName; } else if (field.Equals("SUBJECTDN")) { findType = X509FindType.FindBySubjectDistinguishedName; } else if (field.Equals("ISSUER")) { findType = X509FindType.FindByIssuerName; } else if (field.Equals("ISSUERDN")) { findType = X509FindType.FindByIssuerDistinguishedName; } else if (field.Equals("THUMBPRINT")) { findType = X509FindType.FindByThumbprint; } else if (field.Equals("SUBJECTKEYID")) { findType = X509FindType.FindBySubjectKeyIdentifier; } else if (field.Equals("SERIAL")) { findType = X509FindType.FindBySerialNumber; } else { Ice.PluginInitializationException e = new Ice.PluginInitializationException(); e.reason = "IceSSL: unknown key in `" + value + "'"; throw e; } // // Parse the argument. // start = pos + 1; while (start < value.Length && (value[start] == ' ' || value[start] == '\t')) { ++start; } if (start == value.Length) { Ice.PluginInitializationException e = new Ice.PluginInitializationException(); e.reason = "IceSSL: missing argument in `" + value + "'"; throw e; } string arg; if (value[start] == '"' || value[start] == '\'') { int end = start; ++end; while (end < value.Length) { if (value[end] == value[start] && value[end - 1] != '\\') { break; } ++end; } if (end == value.Length || value[end] != value[start]) { Ice.PluginInitializationException e = new Ice.PluginInitializationException(); e.reason = "IceSSL: unmatched quote in `" + value + "'"; throw e; } ++start; arg = value.Substring(start, end - start); start = end + 1; } else { char[] ws = new char[] { ' ', '\t' }; int end = value.IndexOfAny(ws, start); if (end == -1) { arg = value.Substring(start); start = value.Length; } else { arg = value.Substring(start, end - start); start = end + 1; } } // // Execute the query. // // TODO: allow user to specify a value for validOnly? // bool validOnly = false; if (findType == X509FindType.FindBySubjectDistinguishedName || findType == X509FindType.FindByIssuerDistinguishedName) { X500DistinguishedNameFlags[] flags = { X500DistinguishedNameFlags.None, X500DistinguishedNameFlags.Reversed, }; X500DistinguishedName dn = new X500DistinguishedName(arg); X509Certificate2Collection r = result; for (int i = 0; i < flags.Length; ++i) { r = result.Find(findType, dn.Decode(flags[i]), validOnly); if (r.Count > 0) { break; } } result = r; } else { result = result.Find(findType, arg, validOnly); } } } } finally { store.Close(); } return(result); }
// // Used only by client SSL code, never returns null. // internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext) { Interop.SspiCli.SecPkgContext_IssuerListInfoEx issuerList = (Interop.SspiCli.SecPkgContext_IssuerListInfoEx)SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX); 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); }
/// <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 X509Certificate2 CreateCert(X509Certificate2 issuer, X500DistinguishedName subjectName, byte[] serialNumber, bool signature, int keySize, CertificateHashAlgorithm hashAlgorithm, DateTime notBefore, DateTime notAfter, X509ExtensionCollection extensions) { CryptoApiMethods.CERT_INFO certInfo = new CryptoApiMethods.CERT_INFO(); RSACryptoServiceProvider key = CreateRSAKey(keySize, signature); IntPtr publicKeyInfoPtr = IntPtr.Zero; X509Certificate2 cert = null; List <X509Extension> newExts = null; if (extensions != null) { foreach (X509Extension ext in extensions) { if (ext.RawData == null) { throw new ArgumentException(Properties.Resources.CreateCert_NeedEncodedData); } } } try { if (serialNumber == null) { serialNumber = Guid.NewGuid().ToByteArray(); } certInfo.dwVersion = (uint)CryptoApiMethods.CertVersion.CERT_V3; certInfo.SerialNumber = new CryptoApiMethods.CRYPTOAPI_BLOB(serialNumber); certInfo.Subject = new CryptoApiMethods.CRYPTOAPI_BLOB(subjectName.RawData); if (issuer == null) { // Self-signed certInfo.Issuer = new CryptoApiMethods.CRYPTOAPI_BLOB(subjectName.RawData); } else { certInfo.Issuer = new CryptoApiMethods.CRYPTOAPI_BLOB(issuer.SubjectName.RawData); } // Never seems to need these set to anything valid? certInfo.SubjectUniqueId = new CryptoApiMethods.CRYPT_BIT_BLOB(); certInfo.IssuerUniqueId = new CryptoApiMethods.CRYPT_BIT_BLOB(); certInfo.NotBefore = DateTimeToFileTime(notBefore); certInfo.NotAfter = DateTimeToFileTime(notAfter); certInfo.SignatureAlgorithm = new CryptoApiMethods.CRYPT_ALGORITHM_IDENTIFIER(); // Doesn't seem to work properly with standard szOID_RSA_SHA1RSA //certInfo.SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_OIWSEC_sha1RSASign; //certInfo.SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_RSA_SHA1RSA; //certInfo.SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_RSA_SHA512RSA; certInfo.SignatureAlgorithm.pszObjId = HashAlgorithmToOID(hashAlgorithm); // Add extension fields publicKeyInfoPtr = ExportPublicKeyInfo(key); certInfo.SubjectPublicKeyInfo = (CryptoApiMethods.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(publicKeyInfoPtr, typeof(CryptoApiMethods.CERT_PUBLIC_KEY_INFO)); newExts = new List <X509Extension>(); if (extensions != null) { // Filter out some extensions we don't want newExts.AddRange( extensions.Cast <X509Extension>().Where( x => !x.Oid.Value.Equals(CryptoApiMethods.szOID_AUTHORITY_KEY_IDENTIFIER) && !x.Oid.Value.Equals(CryptoApiMethods.szOID_SUBJECT_KEY_IDENTIFIER) && !x.Oid.Value.Equals(CryptoApiMethods.szOID_AUTHORITY_KEY_IDENTIFIER2))); } if (issuer != null) { newExts.Add(CreateAuthorityKeyInfo2(issuer.GetSerialNumber(), issuer.SubjectName, (RSACryptoServiceProvider)issuer.PrivateKey)); } else { newExts.Add(CreateAuthorityKeyInfo2(serialNumber, subjectName, key)); } newExts.Add(new X509SubjectKeyIdentifierExtension(HashPublicKeyInfo(key), false)); certInfo.rgExtension = MarshalExtensions(newExts.ToArray()); certInfo.cExtension = (uint)newExts.Count; byte[] certData = EncodeAndSignCertInfo(issuer != null ? issuer.PrivateKey as RSACryptoServiceProvider : key, certInfo, hashAlgorithm); cert = new X509Certificate2(certData, (string)null, X509KeyStorageFlags.Exportable); cert.PrivateKey = key; } finally { if (certInfo.rgExtension != IntPtr.Zero) { Marshal.FreeHGlobal(certInfo.rgExtension); } if (certInfo.Subject != null) { certInfo.Subject.Release(); } if (certInfo.Issuer != null) { certInfo.Issuer.Release(); } if (publicKeyInfoPtr != IntPtr.Zero) { Marshal.FreeHGlobal(publicKeyInfoPtr); } } return(cert); }
public override CertificateRequest GenerateCsr(X500DistinguishedName commonName) { return(new CertificateRequest(commonName, Algorithm, HashAlgorithmName.SHA256)); }
/// <summary> /// Initialize a Certificate builder. /// </summary> protected CertificateBuilderBase(X500DistinguishedName subjectName) { m_issuerName = m_subjectName = subjectName; Initialize(); }
/// <summary> /// Comprueba si dos DN son equivalentes /// </summary> /// <param name="dn"></param> /// <param name="other"></param> /// <returns></returns> private bool EquivalentDN(X500DistinguishedName dn, X500DistinguishedName other) { return(X509Name.GetInstance(Asn1Object.FromByteArray(dn.RawData)).Equivalent(X509Name.GetInstance(Asn1Object.FromByteArray(other.RawData)))); }
/// <summary> /// Initialize a Certificate builder. /// </summary> protected CertificateBuilderBase(string subjectName) { m_issuerName = m_subjectName = new X500DistinguishedName(subjectName); Initialize(); }
void decodeTbsResponse(Asn1Reader tbsResponseData) { tbsResponseData.MoveNext(); if (tbsResponseData.Tag == 160) { //Asn1Reader aversion = new Asn1Reader(tbsResponseData.RawData, tbsResponseData.PayloadStartOffset); Asn1Reader aversion = new Asn1Reader(tbsResponseData); aversion.MoveNext(); Version = aversion.GetPayload()[0] + 1; tbsResponseData.MoveNextCurrentLevel(); } else { Version = 1; } //responderID switch (tbsResponseData.Tag) { case 161: ResponderNameId = new X500DistinguishedName(tbsResponseData.GetPayload()); tbsResponseData.MoveNextCurrentLevel(); break; case 162: tbsResponseData.MoveNext(); StringBuilder SB = new StringBuilder(); foreach (Byte element in tbsResponseData.GetPayload()) { SB.Append(element.ToString("X2")); } ResponderKeyId = SB.ToString(); tbsResponseData.MoveNext(); break; default: throw new Exception("Invalid tag at responderID. Expected 161 (byName) or 162 (byKey)."); } //tbsResponseData.MoveNextCurrentLevel(); ProducedAt = Asn1Utils.DecodeGeneralizedTime(tbsResponseData.GetTagRawData()); if (DateTime.Now < ProducedAt.AddMinutes(-10)) { ResponseErrorInformation += (Int32)OCSPResponseComplianceError.ResponseNotTimeValid; } //responses tbsResponseData.MoveNext(); //single response Asn1Reader responses = new Asn1Reader(tbsResponseData.GetTagRawData()); responses.MoveNext(); Int32 Offset; Responses = new OCSPSingleResponseCollection(); do { Asn1Reader response = new Asn1Reader(responses); Offset = response.NextCurrentLevelOffset; Responses.Add(new OCSPSingleResponse(response)); if (Request != null) { foreach (OCSPSingleResponse item in Responses) { Boolean certidmatch = Request.RequestList.Any(x => x.CertId.Equals(item.CertId)); if (!certidmatch) { ResponseErrorInformation += (Int32)OCSPResponseComplianceError.CertIdMismatch; } } } } while (Offset != 0); if (tbsResponseData.NextCurrentLevelOffset != 0) { tbsResponseData.MoveNextCurrentLevel(); if (tbsResponseData.Tag == 161) { X509ExtensionCollection exts = new X509ExtensionCollection(); exts.Decode(tbsResponseData.GetPayload()); foreach (X509Extension item in exts) { _listExtensions.Add(CryptographyUtils.ConvertExtension(item)); if (_listExtensions[_listExtensions.Count - 1].Oid.Value == X509CertExtensions.X509OcspNonce) { NonceReceived = true; NonceValue = _listExtensions[_listExtensions.Count - 1].Format(false); } } } else { throw new Exception("Unexpected tag at responseExtensions. Expected 161."); } } }
public static void ReproduceBigExponentCert() { DateTimeOffset notBefore = new DateTimeOffset(2016, 3, 2, 1, 48, 0, TimeSpan.Zero); DateTimeOffset notAfter = new DateTimeOffset(2017, 3, 2, 1, 48, 0, TimeSpan.Zero); byte[] serialNumber = "9B5DE6C15126A58B".HexToByteArray(); var subject = new X500DistinguishedName( "CN=localhost, OU=.NET Framework (CoreFX), O=Microsoft Corporation, L=Redmond, S=Washington, C=US"); X509Extension skidExtension = new X509SubjectKeyIdentifierExtension( "78A5C75D51667331D5A96924114C9B5FA00D7BCB", false); X509Extension akidExtension = new X509Extension( "2.5.29.35", "3016801478A5C75D51667331D5A96924114C9B5FA00D7BCB".HexToByteArray(), false); X509Extension basicConstraints = new X509BasicConstraintsExtension(true, false, 0, false); X509Certificate2 cert; using (RSA rsa = RSA.Create()) { rsa.ImportParameters(TestData.RsaBigExponentParams); var request = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); request.CertificateExtensions.Add(skidExtension); request.CertificateExtensions.Add(akidExtension); request.CertificateExtensions.Add(basicConstraints); var signatureGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); cert = request.Create(subject, signatureGenerator, notBefore, notAfter, serialNumber); } const string expectedHex = "308203EB308202D3A0030201020209009B5DE6C15126A58B300D06092A864886" + "F70D01010B050030818A310B3009060355040613025553311330110603550408" + "130A57617368696E67746F6E3110300E060355040713075265646D6F6E64311E" + "301C060355040A13154D6963726F736F667420436F72706F726174696F6E3120" + "301E060355040B13172E4E4554204672616D65776F726B2028436F7265465829" + "31123010060355040313096C6F63616C686F7374301E170D3136303330323031" + "343830305A170D3137303330323031343830305A30818A310B30090603550406" + "13025553311330110603550408130A57617368696E67746F6E3110300E060355" + "040713075265646D6F6E64311E301C060355040A13154D6963726F736F667420" + "436F72706F726174696F6E3120301E060355040B13172E4E4554204672616D65" + "776F726B2028436F726546582931123010060355040313096C6F63616C686F73" + "7430820124300D06092A864886F70D010101050003820111003082010C028201" + "0100AF81C1CBD8203F624A539ED6608175372393A2837D4890E48A19DED36973" + "115620968D6BE0D3DAA38AA777BE02EE0B6B93B724E8DCC12B632B4FA80BBC92" + "5BCE624F4CA7CC606306B39403E28C932D24DD546FFE4EF6A37F10770B2215EA" + "8CBB5BF427E8C4D89B79EB338375100C5F83E55DE9B4466DDFBEEE42539AEF33" + "EF187B7760C3B1A1B2103C2D8144564A0C1039A09C85CF6B5974EB516FC8D662" + "3C94AE3A5A0BB3B4C792957D432391566CF3E2A52AFB0C142B9E0681B8972671" + "AF2B82DD390A39B939CF719568687E4990A63050CA7768DCD6B378842F18FDB1" + "F6D9FF096BAF7BEB98DCF930D66FCFD503F58D41BFF46212E24E3AFC45EA42BD" + "884702050200000441A350304E301D0603551D0E0416041478A5C75D51667331" + "D5A96924114C9B5FA00D7BCB301F0603551D2304183016801478A5C75D516673" + "31D5A96924114C9B5FA00D7BCB300C0603551D13040530030101FF300D06092A" + "864886F70D01010B0500038201010077756D05FFA6ADFED5B6D4AFB540840C6D" + "01CF6B3FA6C973DFD61FCAA0A814FA1E2469019D94B1D856D07DD2B95B8550DF" + "D2085953A494B99EFCBAA7982CE771984F9D4A445FFEE062E8A049736A39FD99" + "4E1FDA0A5DC2B5B0E57A0B10C41BC7FE6A40B24F85977302593E60B98DD4811D" + "47D948EDF8D6E6B5AF80A1827496E20BFD240E467674504D4E4703331D64705C" + "36FB6E14BABFD9CBEEC44B33A8D7B36479900F3C5BBAB69C5E453D180783E250" + "8051B998C038E4622571D2AB891D898E5458828CF18679517D28DBCABF72E813" + "07BFD721B73DDB1751123F99D8FC0D533798C4DBD14719D5D8A85B00A144A367" + "677B48891A9B56F045334811BACB7A"; using (cert) { Assert.Equal(expectedHex, cert.RawData.ByteArrayToHex()); } }
public static void NotQuotedWithQuotes(string quoted, string notQuoted, string hexEncoded) { byte[] encoded = hexEncoded.HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal(notQuoted, dn.Decode(X500DistinguishedNameFlags.DoNotUseQuotes)); }
internal static X509Certificate2 CreateSelfSignedCertificate(string commonName, string country, string state, string locality, string organization, string organizationUnit, SecureString password, string friendlyName, DateTimeOffset from, DateTimeOffset to) { SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder(); sanBuilder.AddDnsName("localhost"); sanBuilder.AddDnsName(Environment.MachineName); var x500Values = new List <string>(); if (!string.IsNullOrWhiteSpace(commonName)) { x500Values.Add($"CN={commonName}"); } if (!string.IsNullOrWhiteSpace(country)) { x500Values.Add($"C={country}"); } if (!string.IsNullOrWhiteSpace(state)) { x500Values.Add($"S={state}"); } if (!string.IsNullOrWhiteSpace(locality)) { x500Values.Add($"L={locality}"); } if (!string.IsNullOrWhiteSpace(organization)) { x500Values.Add($"O={organization}"); } if (!string.IsNullOrWhiteSpace(organizationUnit)) { x500Values.Add($"OU={organizationUnit}"); } string distinguishedNameString = string.Join("; ", x500Values); X500DistinguishedName distinguishedName = new X500DistinguishedName(distinguishedNameString); using (RSA rsa = MakeExportable(new RSACng(2048))) { var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); request.CertificateExtensions.Add( new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false)); request.CertificateExtensions.Add( new X509EnhancedKeyUsageExtension( new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false)); request.CertificateExtensions.Add(sanBuilder.Build()); var certificate = request.CreateSelfSigned(from, to); if (Platform.IsWindows) { certificate.FriendlyName = friendlyName; } return(new X509Certificate2(certificate.Export(X509ContentType.Pfx, password), password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet)); } }
public static void PrintComplexForwards() { byte[] encoded = MicrosoftDotComSubject.HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); const string expected = ", SERIALNUMBER=600413485, C=US, PostalCode=98052, S=Washington, L=Redmond, " + "STREET=1 Microsoft Way, O=Microsoft Corporation, OU=MSCOM, CN=www.microsoft.com"; Assert.EndsWith(expected, dn.Decode(X500DistinguishedNameFlags.None), StringComparison.Ordinal); }
public X500DistinguishedName(X500DistinguishedName distinguishedName);
public static void FractionalSecondsNotWritten(bool selfSigned) { using (X509Certificate2 savedCert = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword)) using (RSA rsa = savedCert.GetRSAPrivateKey()) { X500DistinguishedName subjectName = new X500DistinguishedName("CN=Test"); var request = new CertificateRequest( subjectName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); // notBefore is a date before 2050 UTC (encoded using UTC TIME), // notAfter is a date after 2050 UTC (encoded using GENERALIZED TIME). DateTimeOffset notBefore = new DateTimeOffset(2049, 3, 4, 5, 6, 7, 89, TimeSpan.Zero); DateTimeOffset notAfter = notBefore.AddYears(2); Assert.NotEqual(0, notAfter.Millisecond); DateTimeOffset normalizedBefore = notBefore.AddMilliseconds(-notBefore.Millisecond); DateTimeOffset normalizedAfter = notAfter.AddMilliseconds(-notAfter.Millisecond); byte[] manualSerialNumber = { 3, 2, 1 }; X509Certificate2 cert; if (selfSigned) { cert = request.CreateSelfSigned(notBefore, notAfter); } else { cert = request.Create( subjectName, X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1), notBefore, notAfter, manualSerialNumber); } using (cert) { Assert.Equal(normalizedBefore.DateTime.ToLocalTime(), cert.NotBefore); Assert.Equal(normalizedAfter.DateTime.ToLocalTime(), cert.NotAfter); if (selfSigned) { // The serial number used in CreateSelfSigned is random, so find the issuer name, // and the validity period is the next 34 bytes. Verify it was encoded as expected. // // Since the random serial number is at most 9 bytes and the subjectName encoded // value is 17 bytes, there's no chance of an early false match. byte[] encodedCert = cert.RawData; byte[] needle = subjectName.RawData; int index = encodedCert.AsSpan().IndexOf(needle); Assert.Equal( "3020170D3439303330343035303630375A180F32303531303330343035303630375A", encodedCert.AsSpan(index + needle.Length, 34).ByteArrayToHex()); } else { // The entire encoding is deterministic in this mode. Assert.Equal( "308201953081FFA0030201020203030201300D06092A864886F70D01010B0500" + "300F310D300B06035504031304546573743020170D3439303330343035303630" + "375A180F32303531303330343035303630375A300F310D300B06035504031304" + "5465737430819F300D06092A864886F70D010101050003818D00308189028181" + "00B11E30EA87424A371E30227E933CE6BE0E65FF1C189D0D888EC8FF13AA7B42" + "B68056128322B21F2B6976609B62B6BC4CF2E55FF5AE64E9B68C78A3C2DACC91" + "6A1BC7322DD353B32898675CFB5B298B176D978B1F12313E3D865BC53465A11C" + "CA106870A4B5D50A2C410938240E92B64902BAEA23EB093D9599E9E372E48336" + "730203010001300D06092A864886F70D01010B0500038181000095ABC7CC7B01" + "9C2A88A7891165B6ACCDBC5137D80C0A5151B11FD4D789CCE808412ABF05FFB1" + "D9BE097776147A6D4C3EE177E5F9C2C9E8C005D72A6473F9904185B95634BFB4" + "EA80B232B271DC1BF20A2FDC46FC93771636B618F29417C31D5F602236FDB414" + "CDC1BEDE700E31E80DC5E7BB7D3F367420B72925605C916BDA", cert.RawData.ByteArrayToHex()); } } } }
/// <summary> /// Generates and sends a CSR to Xboot.Server REST endpoint. /// </summary> /// <param name="registrationId"></param> /// <param name="name"></param> /// <returns>Pfx in DER-encoded byte array</returns> public byte[] GetDeviceCertificate(string registrationId, X500DistinguishedName name) { byte[] pfx = null; var req = new CertificateRequest(name, _rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pss); // Returns a DER-encoded PKCS#10 CSR var csr = req.CreateSigningRequest(); Certificate_Request request = new Certificate_Request { RegistrationId = registrationId, Csr = Convert.ToBase64String(csr) }; var json = JsonConvert.SerializeObject(request); var client = new HttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); var buffer = System.Text.Encoding.UTF8.GetBytes(json); var byteContent = new ByteArrayContent(buffer); try { var response = client.PostAsync(_xBootUri, byteContent).Result; if (response.IsSuccessStatusCode) { // Get the response var jsonString = response.Content.ReadAsStringAsync().Result; var certString = JsonConvert.DeserializeObject <Certificate_Response>(jsonString); byte[] certBytes = Convert.FromBase64String(certString.Certificate); // Read in signed device certificate in DER format X509Certificate2 cert = new X509Certificate2(certBytes); // Add private key to cert cert = cert.CopyWithPrivateKey(_rsa); if (cert.HasPrivateKey) { // Combine certificate and private key into single pfx // The IoT Device SDK needs both the certificate and the private key information. // It expects to load a single PFX-formatted file containing all necessarily information. pfx = cert.Export(X509ContentType.Pfx); } } else { throw new Exception(response.StatusCode.ToString()); } } catch (Exception ex) { throw new Exception(ex.Message); } // Return certificate in DER-encoded byte array return(pfx); }
public static void QuoteByContents(string expected, string hexEncoded) { byte[] encoded = hexEncoded.HexToByteArray(); X500DistinguishedName dn = new X500DistinguishedName(encoded); Assert.Equal(expected, dn.Decode(X500DistinguishedNameFlags.None)); }
public static void NameWithSTIdentifierForState() { X500DistinguishedName dn = new X500DistinguishedName("ST=VA, C=US"); Assert.Equal("C=US, S=VA", dn.Decode(X500DistinguishedNameFlags.None)); }
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 (); }
public static Claim CreateX500DistinguishedNameClaim( X500DistinguishedName x500DistinguishedName) { return(new Claim(ClaimTypes.X500DistinguishedName, x500DistinguishedName, Rights.PossessProperty)); }
/// <summary> /// Create a self-signed certificate. /// </summary> internal static byte[] CreateSelfSignedCert( X500DistinguishedName subjectName, string friendlyName, DateTime startTime, DateTime endTime, SecureString password) { byte[] pfxData; SystemTime startSystemTime = ToSystemTime(startTime); SystemTime endSystemTime = ToSystemTime(endTime); string containerName = Guid.NewGuid().ToString(); IntPtr providerContext = IntPtr.Zero; IntPtr cryptKey = IntPtr.Zero; IntPtr certContext = IntPtr.Zero; IntPtr certStore = IntPtr.Zero; IntPtr storeCertContext = IntPtr.Zero; IntPtr passwordPtr = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { Check(NativeMethods.CryptAcquireContextW( out providerContext, containerName, null, 1, // PROV_RSA_FULL 8)); // CRYPT_NEWKEYSET Check(NativeMethods.CryptGenKey( providerContext, 1, // AT_KEYEXCHANGE 1 | (KeySize << 16), // CRYPT_EXPORTABLE out cryptKey)); unsafe { fixed(char *pContainerName = containerName.ToCharArray()) { CryptKeyProviderInformation kpi = new CryptKeyProviderInformation(); kpi.ContainerName = (IntPtr)pContainerName; kpi.ProviderType = 1; // PROV_RSA_FULL kpi.KeySpec = 1; // AT_KEYEXCHANGE fixed(byte *pSubjectName = &subjectName.RawData[0]) { CryptoApiBlob nameBlob = new CryptoApiBlob( subjectName.RawData.Length, (IntPtr)pSubjectName); certContext = NativeMethods.CertCreateSelfSignCertificate( providerContext, ref nameBlob, 0, ref kpi, IntPtr.Zero, // default = SHA1RSA ref startSystemTime, ref endSystemTime, IntPtr.Zero); Check(certContext != IntPtr.Zero); } certStore = NativeMethods.CertOpenStore( "Memory", // sz_CERT_STORE_PROV_MEMORY 0, IntPtr.Zero, 0x2000, // CERT_STORE_CREATE_NEW_FLAG IntPtr.Zero); Check(certStore != IntPtr.Zero); Check(NativeMethods.CertAddCertificateContextToStore( certStore, certContext, 1, // CERT_STORE_ADD_NEW out storeCertContext)); NativeMethods.CertSetCertificateContextProperty( storeCertContext, 2, // CERT_KEY_PROV_INFO_PROP_ID 0, (IntPtr)(&kpi)); } fixed(char *pFriendlyName = friendlyName.ToCharArray()) { var blob = new CryptoApiBlob( friendlyName.Length * sizeof(char), (IntPtr)pFriendlyName); NativeMethods.CertSetCertificateContextProperty( storeCertContext, 11, // CERT_FRIENDLY_NAME_PROP_ID 0, (IntPtr)(&blob)); } if (password != null && password.Length > 0) { passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password); } CryptoApiBlob pfxBlob = new CryptoApiBlob(); Check(NativeMethods.PFXExportCertStoreEx( certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY pfxData = new byte[pfxBlob.DataLength]; fixed(byte *pData = pfxData) { pfxBlob.Data = (IntPtr)pData; Check(NativeMethods.PFXExportCertStoreEx( certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY } } } finally { if (passwordPtr != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr); } if (certContext != IntPtr.Zero) { NativeMethods.CertFreeCertificateContext(certContext); } if (storeCertContext != IntPtr.Zero) { NativeMethods.CertFreeCertificateContext(storeCertContext); } if (certStore != IntPtr.Zero) { NativeMethods.CertCloseStore(certStore, 0); } if (cryptKey != IntPtr.Zero) { NativeMethods.CryptDestroyKey(cryptKey); } if (providerContext != IntPtr.Zero) { NativeMethods.CryptReleaseContext(providerContext, 0); NativeMethods.CryptAcquireContextW( out providerContext, containerName, null, 1, // PROV_RSA_FULL 0x10); // CRYPT_DELETEKEYSET } } return(pfxData); }
public abstract CertificateRequest GenerateCsr(X500DistinguishedName dn);
public static void TestFormat(bool multiLine) { // The Issuer field from the Microsoft.com test cert. byte[] encoding = ( "3077310B3009060355040613025553311D301B060355040A131453796D616E74" + "656320436F72706F726174696F6E311F301D060355040B131653796D616E7465" + "63205472757374204E6574776F726B312830260603550403131F53796D616E74" + "656320436C61737320332045562053534C204341202D204733").HexToByteArray(); X500DistinguishedName name = new X500DistinguishedName(encoding); string formatted = name.Format(multiLine); string expected; if (multiLine) { expected = string.Format( "C=US{0}O=Symantec Corporation{0}OU=Symantec Trust Network{0}CN=Symantec Class 3 EV SSL CA - G3{0}", Environment.NewLine); } else { expected = "C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3"; } Assert.Equal(expected, formatted); }
/// <inheritdoc/> public async Task <Certificate> CreateCertificateAndPrivateKeyAsync(string rootCertificate, string certificateName, X500DistinguishedName subjectName, DateTime?notBefore, CreateKeyParams keyParams, Func <byte[], IEnumerable <X509Extension> > extensions, CancellationToken ct) { try { // (0) Retrieve issuer certificate var caCertBundle = await _keyVaultClient.GetCertificateAsync( _vaultBaseUrl, rootCertificate, ct); if (caCertBundle == null) { throw new ResourceNotFoundException("Issuer cert not found."); } var caCert = await _certificates.FindCertificateAsync( caCertBundle.CertificateIdentifier.Identifier); if (caCert?.IssuerPolicies == null) { throw new ArgumentException("Certificate cannot issue."); } // (1) Create key in key vault and get CSR. // policy unknown issuer, new key, exportable key var policyUnknownNewExportable = CreateCertificatePolicy( subjectName.Name, keyParams, false, _keyStoreIsHsm, false, true); var attributes = CreateCertificateAttributes(notBefore, caCert.IssuerPolicies.IssuedLifetime.Value, caCert.NotAfterUtc); var createResult = await CreateCertificateAsync(certificateName, policyUnknownNewExportable, attributes, null, ct); if (createResult.Csr == null) { throw new CryptographicUnexpectedOperationException( "Failed to read CSR from CreateCertificate."); } // decode the CSR and verify consistency var info = createResult.Csr.ToCertificationRequest(); try { // (2) - Issue X509 Certificate with csr and root certificate. // create signed cert var signedcert = await _factory.CreateCertificateAsync(this, caCert, subjectName, info.PublicKey, attributes.NotBefore.Value, attributes.Expires.Value, caCert.IssuerPolicies.SignatureType.Value, false, extensions, ct); // (3) - Complete certificate creation with merger of X509 Certificate. var mergeResult = await _keyVaultClient.MergeCertificateAsync( _vaultBaseUrl, certificateName, new X509Certificate2Collection(signedcert), null, null, ct); // (4) - Get merged certificate and key identifier var mergedCert = await _keyVaultClient.GetCertificateAsync( mergeResult.CertificateIdentifier.Identifier, ct); var cert = CertificateEx.Create(mergedCert.Cer, new KeyVaultKeyHandle(mergedCert)); System.Diagnostics.Debug.Assert(!cert.IsIssuer()); await _certificates.AddCertificateAsync(certificateName, cert, mergedCert.CertificateIdentifier.Identifier, ct); return(cert); } catch { await _keyVaultClient.DeleteCertificateAsync( _vaultBaseUrl, certificateName, ct); await Try.Async(() => _keyVaultClient.PurgeDeletedCertificateAsync( _vaultBaseUrl, certificateName, ct)); throw; } } catch (KeyVaultErrorException ex) { throw new ExternalDependencyException( "Failed to create new key pair certificate", ex); } }