internal static unsafe int BuildChain(IntPtr hChainEngine, System.Security.Cryptography.SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext"); SafeCertStoreHandle hAdditionalStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) hAdditionalStore = X509Utils.ExportToMemoryStore(extraStore); CAPI.CERT_CHAIN_PARA pChainPara = new CAPI.CERT_CHAIN_PARA(); pChainPara.cbSize = (uint)Marshal.SizeOf((object)pChainPara); SafeLocalAllocHandle localAllocHandle1 = SafeLocalAllocHandle.InvalidHandle; if (applicationPolicy != null && applicationPolicy.Count > 0) { pChainPara.RequestedUsage.dwType = 0U; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count; localAllocHandle1 = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = localAllocHandle1.DangerousGetHandle(); } SafeLocalAllocHandle localAllocHandle2 = SafeLocalAllocHandle.InvalidHandle; if (certificatePolicy != null && certificatePolicy.Count > 0) { pChainPara.RequestedIssuancePolicy.dwType = 0U; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count; localAllocHandle2 = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = localAllocHandle2.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *(long*)&pTime = verificationTime.ToFileTime(); uint dwFlags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) return Marshal.GetHRForLastWin32Error(); localAllocHandle1.Dispose(); localAllocHandle2.Dispose(); return 0; }
//BUG [ExpectedException (typeof (ArgumentNullException))] public void AddNull () { OidCollection oc = new OidCollection (); oc.Add (null); AssertEquals ("Count", 1, oc.Count); // AssertNull ("[0]", oc); throw NullReferenceException }
//BUG [ExpectedException (typeof (ArgumentNullException))] public void AddNull () { OidCollection oc = new OidCollection (); oc.Add (null); Assert.AreEqual (1, oc.Count, "Count"); // Assert.IsNull (oc, "[0]"); throw NullReferenceException }
public void CopyToOidNull () { OidCollection oc = new OidCollection (); oc.Add (new Oid ("1.0")); Oid[] array = null; oc.CopyTo (array, 0); }
private OidEnumerator GetEnumerator () { OidCollection oc = new OidCollection (); oc.Add (new Oid ("1.0")); oc.Add (new Oid ("1.1")); oc.Add (new Oid ("1.2")); return oc.GetEnumerator (); }
public void Add () { OidCollection oc = new OidCollection (); oc.Add (new Oid ("1.0")); Assert.AreEqual (1, oc.Count, "Count"); Assert.AreEqual ("1.0", oc [0].Value, "[0]"); Assert.AreEqual ("1.0", oc ["1.0"].Value, "['1.0']"); }
public void Add () { OidCollection oc = new OidCollection (); oc.Add (new Oid ("1.0")); AssertEquals ("Count", 1, oc.Count); AssertEquals ("[0]", "1.0", oc [0].Value); AssertEquals ("['1.0']", "1.0", oc ["1.0"].Value); }
public void CopyToOid () { OidCollection oc = new OidCollection (); oc.Add (new Oid ("1.0")); Oid[] array = new Oid [1]; oc.CopyTo (array, 0); Assert.AreEqual ("1.0", array [0].Value, "CopyTo(Oid)"); }
public void Constructor () { OidCollection oc = new OidCollection (); // default properties Assert.AreEqual (0, oc.Count, "Count"); Assert.IsTrue (!oc.IsSynchronized, "IsSynchronized"); Assert.IsNotNull (oc.SyncRoot, "SyncRoot"); Assert.IsNotNull (oc.GetEnumerator (), "GetEnumerator"); }
public void Constructor () { OidCollection oc = new OidCollection (); // default properties AssertEquals ("Count", 0, oc.Count); Assert ("IsSynchronized", !oc.IsSynchronized); AssertNotNull ("SyncRoot", oc.SyncRoot); AssertNotNull ("GetEnumerator", oc.GetEnumerator ()); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } TimeSpan remainingDownloadTime = timeout; var leaf = new X509Certificate2(cert.Handle); var downloaded = new HashSet<X509Certificate2>(); var systemTrusted = new HashSet<X509Certificate2>(); HashSet<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, systemTrusted, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, systemTrusted, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, ref remainingDownloadTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
/// <summary> /// Does not throw on error. Returns null ChainPal instead. /// </summary> public static ChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CertificatePal certificatePal = (CertificatePal)cert; unsafe { using (SafeCertStoreHandle extraStoreHandle = ConvertExtraStoreToSafeHandle(extraStore)) { CERT_CHAIN_PARA chainPara = new CERT_CHAIN_PARA(); chainPara.cbSize = Marshal.SizeOf<CERT_CHAIN_PARA>(); int applicationPolicyCount; using (SafeHandle applicationPolicyOids = applicationPolicy.ToLpstrArray(out applicationPolicyCount)) { if (!applicationPolicyOids.IsInvalid) { chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedUsage.Usage.cUsageIdentifier = applicationPolicyCount; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle(); } int certificatePolicyCount; using (SafeHandle certificatePolicyOids = certificatePolicy.ToLpstrArray(out certificatePolicyCount)) { if (!certificatePolicyOids.IsInvalid) { chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount; chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle(); } chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds); FILETIME ft = FILETIME.FromDateTime(verificationTime); CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag); ChainEngine chainEngine = useMachineContext ? ChainEngine.HCCE_LOCAL_MACHINE : ChainEngine.HCCE_CURRENT_USER; SafeX509ChainHandle chain; if (!Interop.crypt32.CertGetCertificateChain(chainEngine, certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) return null; return new ChainPal(chain); } } } } }
public void Reset() { this.m_applicationPolicy = new OidCollection(); this.m_certificatePolicy = new OidCollection(); this.m_revocationMode = X509RevocationMode.Online; this.m_revocationFlag = X509RevocationFlag.ExcludeRoot; this.m_verificationFlags = X509VerificationFlags.NoFlag; this.m_verificationTime = DateTime.Now; this.m_timeout = new TimeSpan(0, 0, 0); this.m_extraStore = new X509Certificate2Collection(); }
internal OidCollection ReadOnlyCopy() { OidCollection copy = new OidCollection(); foreach (Oid oid in _list) { copy.Add(oid); } copy._readOnly = true; return(copy); }
internal OidCollection ReadOnlyCopy() { OidCollection oidCollection = new OidCollection(); foreach (object obj in this._list) { Oid oid = (Oid)obj; oidCollection.Add(oid); } oidCollection._readOnly = true; return(oidCollection); }
internal bool MatchesCertificatePolicies(OidCollection policyOids) { foreach (Oid oid in policyOids) { if (!MatchesCertificatePolicies(oid)) { return false; } } return true; }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { return new OpenSslX509ChainProcessor(); }
private static unsafe void BuildChain(IntPtr hChainEngine, IntPtr pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, out System.IdentityModel.SafeCertChainHandle ppChainContext) { System.IdentityModel.SafeCertStoreHandle hAdditionalStore = ExportToMemoryStore(extraStore, pCertContext); System.IdentityModel.CAPI.CERT_CHAIN_PARA pChainPara = new System.IdentityModel.CAPI.CERT_CHAIN_PARA { cbSize = (uint) Marshal.SizeOf(typeof(System.IdentityModel.CAPI.CERT_CHAIN_PARA)) }; SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle; SafeHGlobalHandle handle3 = SafeHGlobalHandle.InvalidHandle; try { if ((applicationPolicy != null) && (applicationPolicy.Count > 0)) { pChainPara.RequestedUsage.dwType = 0; pChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count; invalidHandle = CopyOidsToUnmanagedMemory(applicationPolicy); pChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = invalidHandle.DangerousGetHandle(); } if ((certificatePolicy != null) && (certificatePolicy.Count > 0)) { pChainPara.RequestedIssuancePolicy.dwType = 0; pChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count; handle3 = CopyOidsToUnmanagedMemory(certificatePolicy); pChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = handle3.DangerousGetHandle(); } pChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds; System.Runtime.InteropServices.ComTypes.FILETIME pTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); *((long*) &pTime) = verificationTime.ToFileTime(); uint dwFlags = MapRevocationFlags(revocationMode, revocationFlag); if (!System.IdentityModel.CAPI.CertGetCertificateChain(hChainEngine, pCertContext, ref pTime, hAdditionalStore, ref pChainPara, dwFlags, IntPtr.Zero, out ppChainContext)) { int hr = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(hr)); } } finally { if (invalidHandle != null) { invalidHandle.Dispose(); } if (handle3 != null) { handle3.Dispose(); } hAdditionalStore.Close(); } }
public static X509Certificate2 CreateRsaCertificate( string dnsName, int validityPeriodInYears) { BasicConstraints basicConstraints = new BasicConstraints { CertificateAuthority = false, HasPathLengthConstraint = false, PathLengthConstraint = 0, Critical = false }; SubjectAlternativeName subjectAlternativeName = new SubjectAlternativeName { DnsName = new List <string> { dnsName } }; X509KeyUsageFlags x509KeyUsageFlags = X509KeyUsageFlags.DigitalSignature; OidCollection enhancedKeyUsages = new System.Security.Cryptography.OidCollection { new Oid("1.3.6.1.5.5.7.3.1"), // TLS Server auth new Oid("1.3.6.1.5.5.7.3.2"), // TLS Client auth }; X509Certificate2 certificate = _cc.NewRsaSelfSignedCertificate( new DistinguishedName { CommonName = dnsName }, basicConstraints, new ValidityPeriod { ValidFrom = DateTimeOffset.UtcNow, ValidTo = DateTimeOffset.UtcNow.AddYears(validityPeriodInYears) }, subjectAlternativeName, enhancedKeyUsages, x509KeyUsageFlags, new RsaConfiguration { KeySize = 2048 } ); return(certificate); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CheckRevocationMode(revocationMode); // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } TimeSpan remainingDownloadTime = timeout; X509Certificate2 leaf = new X509Certificate2(cert.Handle); List<X509Certificate2> downloaded = new List<X509Certificate2>(); List<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, applicationPolicy, certificatePolicy, verificationTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
/// <summary> /// Creates a new self-signed X509 certificate /// </summary> /// <param name="issuer">The certificate issuer</param> /// <param name="friendlyName">Human readable name</param> /// <param name="password">The certificate's password</param> /// <param name="startTime">Certificate creation date & time</param> /// <param name="endTime">Certificate expiry date & time</param> /// <returns>An X509Certificate2</returns> public static X509Certificate2 CreateSelfSignedCert(string issuer, string friendlyName, string password, DateTime startTime, DateTime endTime) { string distinguishedNameString = issuer; var key = Create2048RsaKey(); var creationParams = new X509CertificateCreationParameters(new X500DistinguishedName(distinguishedNameString)) { TakeOwnershipOfKey = true, StartTime = startTime, EndTime = endTime }; // adding client authentication, -eku = 1.3.6.1.5.5.7.3.2, // This is mandatory for the upload to be successful OidCollection oidCollection = new OidCollection(); oidCollection.Add(new Oid(OIDClientAuthValue, OIDClientAuthFriendlyName)); creationParams.Extensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, false)); // Documentation of CreateSelfSignedCertificate states: // If creationParameters have TakeOwnershipOfKey set to true, the certificate // generated will own the key and the input CngKey will be disposed to ensure // that the caller doesn't accidentally use it beyond its lifetime (which is // now controlled by the certificate object). // We don't dispose it ourselves in this case. var cert = key.CreateSelfSignedCertificate(creationParams); key = null; cert.FriendlyName = friendlyName; // X509 certificate needs PersistKeySet flag set. // Reload a new X509Certificate2 instance from exported bytes in order to set the PersistKeySet flag. var bytes = cert.Export(X509ContentType.Pfx, password); // NOTE: PfxValidation is not done here because these are newly created certs and assumed valid. ICommonEventSource evtSource = null; return X509Certificate2Helper.NewX509Certificate2(bytes, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable, evtSource, doPfxValidation: false); }
internal static unsafe int BuildChain (IntPtr hChainEngine, SafeCertContextHandle pCertContext, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, ref SafeCertChainHandle ppChainContext) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException(SecurityResources.GetResourceString("Cryptography_InvalidContextHandle"), "pCertContext"); SafeCertStoreHandle hCertStore = SafeCertStoreHandle.InvalidHandle; if (extraStore != null && extraStore.Count > 0) hCertStore = X509Utils.ExportToMemoryStore(extraStore); CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA(); // Initialize the structure size. ChainPara.cbSize = (uint) Marshal.SizeOf(ChainPara); // Application policy SafeLocalAllocHandle applicationPolicyHandle = SafeLocalAllocHandle.InvalidHandle; if (applicationPolicy != null && applicationPolicy.Count > 0) { ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint) applicationPolicy.Count; applicationPolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(applicationPolicy); ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle(); } // Certificate policy SafeLocalAllocHandle certificatePolicyHandle = SafeLocalAllocHandle.InvalidHandle; if (certificatePolicy != null && certificatePolicy.Count > 0) { ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND; ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint) certificatePolicy.Count; certificatePolicyHandle = X509Utils.CopyOidsToUnmanagedMemory(certificatePolicy); ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle(); } ChainPara.dwUrlRetrievalTimeout = (uint) timeout.Milliseconds; _FILETIME ft = new _FILETIME(); *((long*) &ft) = verificationTime.ToFileTime(); uint flags = X509Utils.MapRevocationFlags(revocationMode, revocationFlag); // Build the chain. if (!CAPI.CAPISafe.CertGetCertificateChain(hChainEngine, pCertContext, ref ft, hCertStore, ref ChainPara, flags, IntPtr.Zero, ref ppChainContext)) return Marshal.GetHRForLastWin32Error(); applicationPolicyHandle.Dispose(); certificatePolicyHandle.Dispose(); return CAPI.S_OK; }
internal OidEnumerator(OidCollection collection) { this._collection = collection; this._position = -1; }
// note: couldn't reuse the IEnumerator from ArrayList because // it doesn't throw the same exceptions internal OidEnumerator(OidCollection collection) { _collection = collection; _position = -1; }
public void DecodeX509EnhancedKeyUsageExtension(byte[] encoded, out OidCollection usages) { OidCollection localUsages = new OidCollection(); unsafe { encoded.DecodeObject( CryptDecodeObjectStructType.X509_ENHANCED_KEY_USAGE, delegate (void* pvDecoded) { CERT_ENHKEY_USAGE* pEnhKeyUsage = (CERT_ENHKEY_USAGE*)pvDecoded; int count = pEnhKeyUsage->cUsageIdentifier; for (int i = 0; i < count; i++) { IntPtr oidValuePointer = pEnhKeyUsage->rgpszUsageIdentifier[i]; string oidValue = Marshal.PtrToStringAnsi(oidValuePointer); Oid oid = new Oid(oidValue); localUsages.Add(oid); } } ); } usages = localUsages; }
public byte[] EncodeX509EnhancedKeyUsageExtension(OidCollection usages) { int numUsages; using (SafeHandle usagesSafeHandle = usages.ToLpstrArray(out numUsages)) { unsafe { CERT_ENHKEY_USAGE enhKeyUsage = new CERT_ENHKEY_USAGE() { cUsageIdentifier = numUsages, rgpszUsageIdentifier = (IntPtr*)(usagesSafeHandle.DangerousGetHandle()), }; return Interop.crypt32.EncodeObject(Oids.EnhancedKeyUsage, &enhKeyUsage); } } }
internal OidEnumerator(OidCollection oids) { _oids = oids; _current = -1; }
public static IChainPal BuildChain( X509Certificate2 leaf, HashSet<X509Certificate2> candidates, HashSet<X509Certificate2> downloaded, HashSet<X509Certificate2> systemTrusted, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, ref TimeSpan remainingDownloadTime) { X509ChainElement[] elements; List<X509ChainStatus> overallStatus = new List<X509ChainStatus>(); WorkingChain workingChain = new WorkingChain(); Interop.Crypto.X509StoreVerifyCallback workingCallback = workingChain.VerifyCallback; // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes. // // (If you need to think of it as an X509Store, it's a volatile memory store) using (SafeX509StoreHandle store = Interop.Crypto.X509StoreCreate()) using (SafeX509StoreCtxHandle storeCtx = Interop.Crypto.X509StoreCtxCreate()) { Interop.Crypto.CheckValidOpenSslHandle(store); Interop.Crypto.CheckValidOpenSslHandle(storeCtx); bool lookupCrl = revocationMode != X509RevocationMode.NoCheck; foreach (X509Certificate2 cert in candidates) { OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal; if (!Interop.Crypto.X509StoreAddCert(store, pal.SafeHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } if (lookupCrl) { CrlCache.AddCrlForCertificate( cert, store, revocationMode, verificationTime, ref remainingDownloadTime); // If we only wanted the end-entity certificate CRL then don't look up // any more of them. lookupCrl = revocationFlag != X509RevocationFlag.EndCertificateOnly; } } if (revocationMode != X509RevocationMode.NoCheck) { if (!Interop.Crypto.X509StoreSetRevocationFlag(store, revocationFlag)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } } SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle; if (!Interop.Crypto.X509StoreCtxInit(storeCtx, store, leafHandle)) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } Interop.Crypto.X509StoreCtxSetVerifyCallback(storeCtx, workingCallback); Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime); int verify = Interop.Crypto.X509VerifyCert(storeCtx); if (verify < 0) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Because our callback tells OpenSSL that every problem is ignorable, it should tell us that the // chain is just fine (unless it returned a negative code for an exception) Debug.Assert(verify == 1, "verify == 1"); using (SafeX509StackHandle chainStack = Interop.Crypto.X509StoreCtxGetChain(storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); elements = new X509ChainElement[chainSize]; int maybeRootDepth = chainSize - 1; // The leaf cert is 0, up to (maybe) the root at chainSize - 1 for (int i = 0; i < chainSize; i++) { List<X509ChainStatus> status = new List<X509ChainStatus>(); List<Interop.Crypto.X509VerifyStatusCode> elementErrors = i < workingChain.Errors.Count ? workingChain.Errors[i] : null; if (elementErrors != null) { AddElementStatus(elementErrors, status, overallStatus); } IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (elementCertPtr == IntPtr.Zero) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } // Duplicate the certificate handle X509Certificate2 elementCert = new X509Certificate2(elementCertPtr); // If the last cert is self signed then it's the root cert, do any extra checks. if (i == maybeRootDepth && IsSelfSigned(elementCert)) { // If the root certificate was downloaded or the system // doesn't trust it, it's untrusted. if (downloaded.Contains(elementCert) || !systemTrusted.Contains(elementCert)) { AddElementStatus( Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED, status, overallStatus); } } elements[i] = new X509ChainElement(elementCert, status.ToArray(), ""); } } } GC.KeepAlive(workingCallback); if ((certificatePolicy != null && certificatePolicy.Count > 0) || (applicationPolicy != null && applicationPolicy.Count > 0)) { List<X509Certificate2> certsToRead = new List<X509Certificate2>(); foreach (X509ChainElement element in elements) { certsToRead.Add(element.Certificate); } CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead); bool failsPolicyChecks = false; if (certificatePolicy != null) { if (!policyChain.MatchesCertificatePolicies(certificatePolicy)) { failsPolicyChecks = true; } } if (applicationPolicy != null) { if (!policyChain.MatchesApplicationPolicies(applicationPolicy)) { failsPolicyChecks = true; } } if (failsPolicyChecks) { X509ChainElement leafElement = elements[0]; X509ChainStatus chainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.NotValidForUsage, StatusInformation = SR.Chain_NoPolicyMatch, }; var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1); elementStatus.AddRange(leafElement.ChainElementStatus); AddUniqueStatus(elementStatus, ref chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); elements[0] = new X509ChainElement( leafElement.Certificate, elementStatus.ToArray(), leafElement.Information); } } return new OpenSslX509ChainProcessor { ChainStatus = overallStatus.ToArray(), ChainElements = elements, }; }
internal static SafeLocalAllocHandle CopyOidsToUnmanagedMemory (OidCollection oids) { SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle; if (oids == null || oids.Count == 0) return safeLocalAllocHandle; int ptrSize = oids.Count * Marshal.SizeOf(typeof(IntPtr)); int oidSize = 0; foreach (Oid oid in oids) { oidSize += (oid.Value.Length + 1); } safeLocalAllocHandle = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr((uint) ptrSize + (uint) oidSize)); IntPtr pOid = new IntPtr((long)safeLocalAllocHandle.DangerousGetHandle() + ptrSize); for (int index=0; index < oids.Count; index++) { Marshal.WriteIntPtr(new IntPtr((long) safeLocalAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid); byte[] ansiOid = Encoding.ASCII.GetBytes(oids[index].Value); Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length); pOid = new IntPtr((long) pOid + oids[index].Value.Length + 1); } return safeLocalAllocHandle; }
private static unsafe byte[] EncodeExtension (OidCollection enhancedKeyUsages) { if (enhancedKeyUsages == null) throw new ArgumentNullException("enhancedKeyUsages"); SafeLocalAllocHandle safeLocalAllocHandle = X509Utils.CopyOidsToUnmanagedMemory(enhancedKeyUsages); byte[] encodedEnhancedKeyUsages = null; using (safeLocalAllocHandle) { CAPI.CERT_ENHKEY_USAGE pEnhKeyUsage = new CAPI.CERT_ENHKEY_USAGE(); pEnhKeyUsage.cUsageIdentifier = (uint) enhancedKeyUsages.Count; pEnhKeyUsage.rgpszUsageIdentifier = safeLocalAllocHandle.DangerousGetHandle(); if (!CAPI.EncodeObject(CAPI.szOID_ENHANCED_KEY_USAGE, new IntPtr(&pEnhKeyUsage), out encodedEnhancedKeyUsages)) throw new CryptographicException(Marshal.GetLastWin32Error()); } return encodedEnhancedKeyUsages; }
private void DecodeExtension () { uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_ENHANCED_KEY_USAGE), m_rawData, out decoded, out cbDecoded); if (result == false) throw new CryptographicException(Marshal.GetLastWin32Error()); CAPI.CERT_ENHKEY_USAGE pEnhKeyUsage = (CAPI.CERT_ENHKEY_USAGE) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_ENHKEY_USAGE)); m_enhancedKeyUsages = new OidCollection(); for (int index = 0; index < pEnhKeyUsage.cUsageIdentifier; index++) { IntPtr pszOid = Marshal.ReadIntPtr(new IntPtr((long) pEnhKeyUsage.rgpszUsageIdentifier + index * Marshal.SizeOf(typeof(IntPtr)))); string oidValue = Marshal.PtrToStringAnsi(pszOid); Oid oid = new Oid(oidValue, OidGroup.ExtensionOrAttribute, false); m_enhancedKeyUsages.Add(oid); } m_decoded = true; decoded.Dispose(); }
public X509EnhancedKeyUsageExtension(OidCollection enhancedKeyUsages, bool critical) : base (CAPI.szOID_ENHANCED_KEY_USAGE, EncodeExtension(enhancedKeyUsages), critical) {}
internal static SafeLocalAllocHandle CopyOidsToUnmanagedMemory (OidCollection oids) { SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle; if (oids == null || oids.Count == 0) return safeLocalAllocHandle; // Copy the oid strings to a local list to prevent a security race condition where // the OidCollection or individual oids can be modified by another thread and // potentially cause a buffer overflow List<string> oidStrs = new List<string>(); foreach (Oid oid in oids) { oidStrs.Add(oid.Value); } IntPtr pOid = IntPtr.Zero; // Needs to be checked to avoid having large sets of oids overflow the sizes and allow // a potential buffer overflow checked { int ptrSize = oidStrs.Count * Marshal.SizeOf(typeof(IntPtr)); int oidSize = 0; foreach (string oidStr in oidStrs) { oidSize += (oidStr.Length + 1); } safeLocalAllocHandle = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr((uint)ptrSize + (uint)oidSize)); pOid = new IntPtr((long)safeLocalAllocHandle.DangerousGetHandle() + ptrSize); } for (int index = 0; index < oidStrs.Count; index++) { Marshal.WriteIntPtr(new IntPtr((long) safeLocalAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid); byte[] ansiOid = Encoding.ASCII.GetBytes(oidStrs[index]); Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length); pOid = new IntPtr((long)pOid + oidStrs[index].Length + 1); } return safeLocalAllocHandle; }
internal static unsafe int VerifyCertificate (Cryptography.SafeCertContextHandle pCertContext, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout, X509Certificate2Collection extraStore, IntPtr pszPolicy, IntPtr pdwErrorStatus) { if (pCertContext == null || pCertContext.IsInvalid) throw new ArgumentException("pCertContext"); CAPI.CERT_CHAIN_POLICY_PARA PolicyPara = new CAPI.CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_PARA))); CAPI.CERT_CHAIN_POLICY_STATUS PolicyStatus = new CAPI.CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_POLICY_STATUS))); // Build the chain. SafeX509ChainHandle pChainContext = SafeX509ChainHandle.InvalidHandle; int hr = X509Chain.BuildChain(new IntPtr(CAPI.HCCE_CURRENT_USER), pCertContext, extraStore, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, timeout, ref pChainContext); if (hr != CAPI.S_OK) return hr; // Verify the chain using the specified policy. if (CAPI.CertVerifyCertificateChainPolicy(pszPolicy, pChainContext, ref PolicyPara, ref PolicyStatus)) { if (pdwErrorStatus != IntPtr.Zero) *(uint*) pdwErrorStatus = PolicyStatus.dwError; if (PolicyStatus.dwError != 0) return CAPI.S_FALSE; } else { // The API failed. return Marshal.GetHRForLastWin32Error(); } return CAPI.S_OK; }
public X509EnhancedKeyUsageExtension() : base (CAPI.szOID_ENHANCED_KEY_USAGE) { m_enhancedKeyUsages = new OidCollection(); m_decoded = true; }
public static IChainPal BuildChain( X509Certificate2 leaf, X509Certificate2Collection candidates, OidCollection applicationPolicy, OidCollection certificatePolicy, DateTime verificationTime) { X509ChainElement[] elements; List<X509ChainStatus> overallStatus = new List<X509ChainStatus>(); // An X509_STORE is more comparable to Cryptography.X509Certificate2Collection than to // Cryptography.X509Store. So read this with OpenSSL eyes, not CAPI/CNG eyes. // // (If you need to think of it as an X509Store, it's a volatile memory store) using (SafeX509StoreHandle store = Interop.libcrypto.X509_STORE_new()) using (SafeX509StoreCtxHandle storeCtx = Interop.libcrypto.X509_STORE_CTX_new()) { Interop.libcrypto.CheckValidOpenSslHandle(store); Interop.libcrypto.CheckValidOpenSslHandle(storeCtx); foreach (X509Certificate2 cert in candidates) { OpenSslX509CertificateReader pal = (OpenSslX509CertificateReader)cert.Pal; if (!Interop.libcrypto.X509_STORE_add_cert(store, pal.SafeHandle)) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } } // When CRL checking support is added, it should be done before the call to // X509_STORE_CTX_init (aka here) by calling X509_STORE_set_flags(store, flags); SafeX509Handle leafHandle = ((OpenSslX509CertificateReader)leaf.Pal).SafeHandle; if (!Interop.libcrypto.X509_STORE_CTX_init(storeCtx, store, leafHandle, IntPtr.Zero)) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } Interop.Crypto.SetX509ChainVerifyTime(storeCtx, verificationTime); int verify = Interop.libcrypto.X509_verify_cert(storeCtx); if (verify < 0) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } using (SafeX509StackHandle chainStack = Interop.libcrypto.X509_STORE_CTX_get1_chain(storeCtx)) { int chainSize = Interop.Crypto.GetX509StackFieldCount(chainStack); int errorDepth = -1; Interop.libcrypto.X509VerifyStatusCode errorCode = 0; string errorMsg = null; if (verify == 0) { errorCode = Interop.libcrypto.X509_STORE_CTX_get_error(storeCtx); errorDepth = Interop.libcrypto.X509_STORE_CTX_get_error_depth(storeCtx); errorMsg = Interop.libcrypto.X509_verify_cert_error_string(errorCode); } elements = new X509ChainElement[chainSize]; for (int i = 0; i < chainSize; i++) { List<X509ChainStatus> status = new List<X509ChainStatus>(); if (i == errorDepth) { X509ChainStatus chainStatus = new X509ChainStatus { Status = MapVerifyErrorToChainStatus(errorCode), StatusInformation = errorMsg, }; status.Add(chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); } IntPtr elementCertPtr = Interop.Crypto.GetX509StackField(chainStack, i); if (elementCertPtr == IntPtr.Zero) { throw Interop.libcrypto.CreateOpenSslCryptographicException(); } // Duplicate the certificate handle X509Certificate2 elementCert = new X509Certificate2(elementCertPtr); elements[i] = new X509ChainElement(elementCert, status.ToArray(), ""); } } } if ((certificatePolicy != null && certificatePolicy.Count > 0) || (applicationPolicy != null && applicationPolicy.Count > 0)) { X509Certificate2Collection certsToRead = new X509Certificate2Collection(); foreach (X509ChainElement element in elements) { certsToRead.Add(element.Certificate); } CertificatePolicyChain policyChain = new CertificatePolicyChain(certsToRead); bool failsPolicyChecks = false; if (certificatePolicy != null) { if (!policyChain.MatchesCertificatePolicies(certificatePolicy)) { failsPolicyChecks = true; } } if (applicationPolicy != null) { if (!policyChain.MatchesApplicationPolicies(applicationPolicy)) { failsPolicyChecks = true; } } if (failsPolicyChecks) { X509ChainElement leafElement = elements[0]; X509ChainStatus chainStatus = new X509ChainStatus { Status = X509ChainStatusFlags.InvalidPolicyConstraints, StatusInformation = SR.Chain_NoPolicyMatch, }; var elementStatus = new List<X509ChainStatus>(leafElement.ChainElementStatus.Length + 1); elementStatus.AddRange(leafElement.ChainElementStatus); AddUniqueStatus(elementStatus, ref chainStatus); AddUniqueStatus(overallStatus, ref chainStatus); elements[0] = new X509ChainElement( leafElement.Certificate, elementStatus.ToArray(), leafElement.Information); } } return new OpenSslX509ChainProcessor { ChainStatus = overallStatus.ToArray(), ChainElements = elements, }; }
internal OidEnumerator(OidCollection oids) { this.m_oids = oids; this.m_current = -1; }