/// <summary> /// Initializes a new <see cref="CertificateChain"/> instance from a <see cref="Certificate"/>. /// </summary> /// <param name="cert">The certificate for which a chain is being built.</param> /// <param name="additional">Any additional store to be searched for supporting certificates and CTLs.</param> /// <param name="options">Additional certificate chain options.</param> /// <remarks><paramref name="cert"/> will always be the end certificate.</remarks> /// <exception cref="ArgumentNullException"><paramref name="cert"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while building the certificate chain.</exception> public CertificateChain(Certificate cert, CertificateStore additional, CertificateChainOptions options) { if (cert == null) throw new ArgumentNullException(); IntPtr addstore = additional == null ? IntPtr.Zero : additional.Handle; ChainParameters para = new ChainParameters(); para.cbSize = Marshal.SizeOf(typeof(ChainParameters)); para.RequestedUsagecUsageIdentifier = 0; para.RequestedUsagedwType = 0; para.RequestedUsagergpszUsageIdentifier = IntPtr.Zero; if (SspiProvider.CertGetCertificateChain(IntPtr.Zero, cert.Handle, IntPtr.Zero, addstore, ref para, (int)options, IntPtr.Zero, ref m_Handle) == 0) throw new CertificateException("Unable to find the certificate chain."); m_Certificate = cert; }
/// <summary> /// Initializes a new instance of the <see cref="CertificateStoreCollection"/> class. /// </summary> /// <param name="stores">An array of stores that should be added to the collection.</param> /// <exception cref="ArgumentNullException"><paramref name="stores"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="ArgumentException">One of the <see cref="CertificateStore"/> objects in the array is a <see cref="CertificateStoreCollection"/> instance. This is not allowed to avoid circular dependencies.</exception> /// <exception cref="CertificateException">An error occurs while adding a certificate to the collection.</exception> public CertificateStoreCollection(CertificateStore[] stores) : base(SspiProvider.CertOpenStore(new IntPtr(SecurityConstants.CERT_STORE_PROV_COLLECTION), 0, 0, 0, null), false) { if (stores == null) throw new ArgumentNullException(); for(int i = 0; i < stores.Length; i++) { if (stores[i].ToString() == this.ToString()) { // used in order to avoid circular dependencies throw new ArgumentException("A certificate store collection cannot hold other certificate store collections."); } } for(int i = 0; i < stores.Length; i++) { if (SspiProvider.CertAddStoreToCollection(this.Handle, stores[i].Handle, 0, 0) == 0) throw new CertificateException("Could not add the store to the collection."); } m_Stores = new ArrayList(); // used to hold references to the certificate stores so they cannot be finalized m_Stores.AddRange(stores); }
/// <summary> /// Find a server certificate in the given store. /// </summary> /// <param name="store"></param> /// <returns></returns> public static Certificate FindServerCert(CertificateStore store) { // return store.FindCertificate(new string[] {OID_PKIX_KP_SERVER_AUTH}); return store.FindCertificateByUsage(new string[] {OID_PKIX_KP_SERVER_AUTH}); }
protected SslHandshakeStatus ProcessCertificate(HandshakeMessage message, bool client) { if (client) { if (m_State != HandshakeType.ServerHello) throw new SslException(AlertDescription.UnexpectedMessage, "Certificate message must be preceded by a ServerHello message."); } else { // server if (m_State != HandshakeType.ClientHello) throw new SslException(AlertDescription.UnexpectedMessage, "Certificate message must be preceded by a ClientHello message."); } UpdateHashes(message, HashUpdate.All); // input message Certificate[] certs = null; try { certs = ParseCertificateList(message.fragment); if (certs.Length == 0) { if (!m_MutualAuthentication) return new SslHandshakeStatus(SslStatus.MessageIncomplete, null); } } catch (SslException t) { throw t; } catch (Exception f) { throw new SslException(f, AlertDescription.InternalError, "The Certificate message is invalid."); } CertificateChain chain = null; m_RemoteCertificate = null; if (certs.Length != 0) { m_RemoteCertificate = certs[0]; if (m_RemoteCertificate.GetPublicKeyLength() < 512) { throw new SslException(AlertDescription.HandshakeFailure, "The pulic key should be at least 512 bits."); } CertificateStore cs = new CertificateStore(certs); for(int i = 0; i < certs.Length; i++) { certs[i].Store = cs; } chain = new CertificateChain(m_RemoteCertificate, cs); } VerifyChain(chain, client); return new SslHandshakeStatus(SslStatus.MessageIncomplete, null); }
/// <summary> /// Returns a CertificateStore from a list of cached stores. If the store is not yet cached, it will be created first. /// </summary> /// <param name="name">The name of the store.</param> /// <returns>The cached store.</returns> internal static CertificateStore GetCachedStore(string name) { CertificateStore cs = null; lock(m_CachedStores) { cs = m_CachedStores[name] as CertificateStore; if (cs == null) { cs = new CertificateStore(name); m_CachedStores.Add(name, cs); } } return cs; }
/// <summary> /// Duplicates an exisiting <see cref="CertificateStore"/>. /// </summary> /// <param name="store">The store to duplicate.</param> /// <exception cref="ArgumentNullException"><paramref name="store"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> public CertificateStore(CertificateStore store) { if (store == null) throw new ArgumentNullException(); InitStore(store.m_Handle, true); }
private int TestConstructs() { CertificateStore cs = null; // empty constructor try { cs = new CertificateStore(); if (cs.EnumCertificates().Length != 0) AddError("CS-TC-1"); } catch { AddError("CS-TC-2"); } // string constructor try { cs = new CertificateStore((string)null); AddError("CS-TC-3"); } catch (ArgumentNullException) { } catch { AddError("CS-TC-4"); } try { cs = new CertificateStore("ROOT"); if (cs.EnumCertificates().Length == 0) AddError("CS-TC-5"); // it is _very_ unlikely that the ROOT store is empty } catch { AddError("CS-TC-6"); } // CertificateStore constructor try { cs = new CertificateStore(cs); if (cs.EnumCertificates().Length == 0) AddError("CS-TC-7"); //copy of the ROOT store } catch { AddError("CS-TC-8"); } try { cs = new CertificateStore((CertificateStore)null); AddError("CS-TC-9"); } catch (ArgumentNullException) { } catch { AddError("CS-TC-10"); } // IntPtr constructor try { cs = new CertificateStore(IntPtr.Zero); AddError("CS-TC-11"); } catch (ArgumentException) { } catch { AddError("CS-TC-12"); } try { cs = new CertificateStore(IntPtr.Zero, true); AddError("CS-TC-13"); } catch (ArgumentException) { } catch { AddError("CS-TC-14"); } try { cs = new CertificateStore(new CertificateStore().Handle, true); } catch { AddError("CS-TC-15"); } return 15; }
/// <summary> /// Creates an in memory <see cref="CertificateStore"/> with this <see cref="Certificate"/> in it. /// </summary> /// <param name="withParents"><b>true</b> if the parent certificates should be included [if possible], <b>false</b> otherwise.</param> /// <returns>A CertificateStore instance.</returns> private CertificateStore CreateCertStore(bool withParents) { CertificateStore store = new CertificateStore(); if (withParents) { Certificate[] c = this.GetCertificateChain().GetCertificates(); for (int i = 0; i < c.Length; i++) { store.AddCertificate(c[i]); } } else { store.AddCertificate(this); } return store; }
/// <summary> /// Adds a certificate store to the collection. /// </summary> /// <param name="store">An instance of the <see cref="CertificateStore"/> class.</param> /// <exception cref="ArgumentNullException"><paramref name="store"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="ArgumentException">The specified certificate store is a <see cref="CertificateStoreCollection"/> instance. This is not allowed to avoid circular dependencies.</exception> /// <exception cref="CertificateException">An error occurs while adding the certificate to the collection.</exception> public void AddStore(CertificateStore store) { if (store == null) throw new ArgumentNullException(); if (store.ToString() == this.ToString()) // avoid circular dependencies throw new ArgumentException("A certificate store collection cannot hold other certificate store collections."); if (SspiProvider.CertAddStoreToCollection(this.Handle, store.Handle, 0, 0) == 0) throw new CertificateException("Could not add the store to the collection."); m_Stores.Add(store); }
/// <summary> /// Initializes this <see cref="Certificate"/> instance from a handle. /// </summary> /// <param name="handle">The handle from which to initialize the state of the new instance.</param> /// <param name="duplicate"><b>true</b> if the handle should be duplicated, <b>false</b> otherwise.</param> /// <param name="store">The store that owns the certificate.</param> /// <exception cref="ArgumentException"><paramref name="handle"/> is invalid.</exception> private void InitCertificate(IntPtr handle, bool duplicate, CertificateStore store) { if (handle == IntPtr.Zero) throw new ArgumentException("Invalid certificate handle!"); if (duplicate) m_Handle = SspiProvider.CertDuplicateCertificateContext(handle); else m_Handle = handle; m_Context = (CertificateContext)Marshal.PtrToStructure(handle, typeof(CertificateContext)); var certInfo = (OG_CertificateInfo)Marshal.PtrToStructure(m_Context.pCertInfo, typeof(OG_CertificateInfo)); m_CertInfo = new CertificateInfo() { dwVersion = certInfo.dwVersion.ToInt32(), SerialNumbercbData = certInfo.SerialNumbercbData.ToInt32(), SerialNumberpbData = certInfo.SerialNumberpbData, SignatureAlgorithmpszObjId = certInfo.SignatureAlgorithmpszObjId, SignatureAlgorithmParameterscbData = certInfo.SignatureAlgorithmParameterscbData.ToInt32(), SignatureAlgorithmParameterspbData = certInfo.SignatureAlgorithmParameterspbData, IssuercbData = certInfo.IssuercbData.ToInt32(), IssuerpbData = certInfo.IssuerpbData, NotBefore = certInfo.NotBefore, NotAfter = certInfo.NotAfter, SubjectcbData = certInfo.SubjectcbData.ToInt32(), SubjectpbData = certInfo.SubjectpbData, SubjectPublicKeyInfoAlgorithmpszObjId = certInfo.SubjectPublicKeyInfoAlgorithmpszObjId, SubjectPublicKeyInfoAlgorithmParameterscbData = certInfo.SubjectPublicKeyInfoAlgorithmParameterscbData.ToInt32(), SubjectPublicKeyInfoAlgorithmParameterspbData = certInfo.SubjectPublicKeyInfoAlgorithmParameterspbData, SubjectPublicKeyInfoPublicKeycbData = certInfo.SubjectPublicKeyInfoPublicKeycbData.ToInt32(), SubjectPublicKeyInfoPublicKeypbData = certInfo.SubjectPublicKeyInfoPublicKeypbData, SubjectPublicKeyInfoPublicKeycUnusedBits = certInfo.SubjectPublicKeyInfoPublicKeycUnusedBits.ToInt32(), IssuerUniqueIdcbData = certInfo.IssuerUniqueIdcbData.ToInt32(), IssuerUniqueIdpbData = certInfo.IssuerUniqueIdpbData, IssuerUniqueIdcUnusedBits = certInfo.IssuerUniqueIdcUnusedBits.ToInt32(), SubjectUniqueIdcbData = certInfo.SubjectUniqueIdcbData.ToInt32(), SubjectUniqueIdpbData = certInfo.SubjectUniqueIdpbData, SubjectUniqueIdcUnusedBits = certInfo.SubjectUniqueIdcUnusedBits.ToInt32(), cExtension = certInfo.cExtension.ToInt32(), rgExtension = certInfo.rgExtension }; // end changes OG 2011-10-03 if (store == null) { m_Store = null; } else { m_Store = store; } }
/// <summary> /// Removes a certificate store from the collection. /// </summary> /// <param name="store">An instance of the <see cref="CertificateStore"/> class.</param> /// <exception cref="ArgumentNullException"><paramref name="store"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> public void RemoveStore(CertificateStore store) { if (store == null) throw new ArgumentNullException(); SspiProvider.CertRemoveStoreFromCollection(this.Handle, store.Handle); m_Stores.Remove(store); }
protected byte[] GetDistinguishedNames() { MemoryStream ms = new MemoryStream(); byte[] buffer; CertificateStore cs = new CertificateStore("ROOT"); Certificate c = cs.FindCertificate((Certificate)null); while(c != null) { if( c.IsCurrent ) { bool include = ( c.GetIntendedKeyUsage() & SecurityConstants.CERT_KEY_CERT_SIGN_KEY_USAGE ) != 0; if( !include ) { System.Collections.Specialized.StringCollection usages = c.GetEnhancedKeyUsage(); if( usages.Count == 0 || usages.Contains( "1.3.6.1.5.5.7.3.2" ) ) { include = true; } } if( include ) { buffer = GetDistinguishedName(c); if (ms.Length + buffer.Length + 2 < 65536) { ms.Write(new byte[]{(byte)(buffer.Length / 256), (byte)(buffer.Length % 256)}, 0, 2); ms.Write(buffer, 0, buffer.Length); } else { break; } } } c = cs.FindCertificate( c ); } return ms.ToArray(); }
/// <summary> /// see <see cref="Ch.Elca.Iiop.Security.Ssl.IClientSideAuthentication.GetClientCertificate"/> /// </summary> public override Certificate GetClientCertificate(DistinguishedNameList acceptable) { CertificateStore store = new CertificateStore(m_storeLocation, MY_STORE_NAME); Certificate toCheck = store.FindCertificate(); while(toCheck != null) { if ((toCheck.IsCurrent) && IsClientCertificate(toCheck)) { // check, if the root certificate in the chain is known by the server, if yes // -> server will be able to verify the certificate chain Certificate[] chain = toCheck.GetCertificateChain().GetCertificates(); if (chain.Length >= 1) { // last certificate in the chain is the root certificate if (IsDistinguishedNameInList(chain[chain.Length - 1].GetDistinguishedName(), acceptable)) { return toCheck; } } } toCheck = store.FindCertificate(toCheck); } return null; }
protected Certificate LoadCertificateFromStore(StoreLocation storeLocation, string storeName, string certHashString, string certSubject) { CertificateStore store = new CertificateStore(storeLocation, storeName); if (certHashString != null) { byte[] certHash = GetKeyHashForKeyHashString(certHashString); return store.FindCertificateByHash(certHash); } else { return store.FindCertificateBySubjectString(certSubject); } }
/// <summary> /// Find a client certificate in the given store. /// </summary> /// <param name="store"></param> /// <returns></returns> public static Certificate FindClientCert(CertificateStore store) { //return store.FindCertificate(new string[] {OID_PKIX_KP_CLIENT_AUTH}); return store.FindCertificateByUsage(new string[] {OID_PKIX_KP_CLIENT_AUTH}); }
/// <summary> /// Asks the user to specify a server certificate, stored in a certificate store. /// </summary> /// <returns>A server certificate.</returns> private Certificate GetStoreCert() { try { Console.WriteLine("Enter the name of the store (for instance \"MY\", without the quotes):"); // open the certificate store specified by the user CertificateStore cs = new CertificateStore(Console.ReadLine()); // find a certificate that is suited for server authentication Certificate ret = cs.FindCertificateByUsage(new string[] {"1.3.6.1.5.5.7.3.1"}); if (ret == null) Console.WriteLine("The certificate file does not contain a server authentication certificate."); return ret; } catch { Console.WriteLine("An error occurs while opening the specified store."); return null; } }
/// <summary> /// Initializes a new <see cref="CertificateChain"/> instance from a <see cref="Certificate"/>. /// </summary> /// <param name="cert">The certificate for which a chain is being built.</param> /// <param name="additional">Any additional store to be searched for supporting certificates and CTLs.</param> /// <remarks><paramref name="cert"/> will always be the end certificate.</remarks> /// <exception cref="ArgumentNullException"><paramref name="cert"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while building the certificate chain.</exception> public CertificateChain(Certificate cert, CertificateStore additional) : this(cert, additional, CertificateChainOptions.Default) {}
protected byte[] GetDistinguishedNames() { MemoryStream ms = new MemoryStream(); byte[] buffer; CertificateStore cs = new CertificateStore("ROOT"); Certificate c = cs.FindCertificate((Certificate)null); while(c != null) { if ((c.GetIntendedKeyUsage() & SecurityConstants.CERT_KEY_CERT_SIGN_KEY_USAGE) != 0 && c.IsCurrent) { buffer = GetDistinguishedName(c); if (ms.Length + buffer.Length + 2 < 65536) { ms.Write(new byte[]{(byte)(buffer.Length / 256), (byte)(buffer.Length % 256)}, 0, 2); ms.Write(buffer, 0, buffer.Length); } } c = cs.FindCertificate(c); } return ms.ToArray(); }
/// <summary> /// Initializes this <see cref="Certificate"/> instance from a handle. /// </summary> /// <param name="handle">The handle from which to initialize the state of the new instance.</param> /// <param name="store">The <see cref="CertificateStore"/> that contains the certificate.</param> internal Certificate(IntPtr handle, CertificateStore store) { InitCertificate(handle, false, store); }
/// <summary> /// Creates a new certificate store from a PFX/P12 encoded file. /// </summary> /// <param name="file">The contents of a PFX file.</param> /// <param name="password">The password used to encrypt the private key.</param> /// <param name="exportable"><b>true</b> if the private keys associated with the certificates should be marked as exportable, <b>false</b> otherwise.</param> /// <param name="location">One of the <see cref="KeysetLocation"/> values.</param> /// <returns>A <see cref="CertificateStore"/> instance.</returns> /// <exception cref="ArgumentNullException"><paramref name="file"/> or <paramref name="password"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="ArgumentException"><paramref name="password"/> is invalid.</exception> /// <exception cref="CertificateException">An error occurs while loading the PFX file.</exception> // Thanks go out to Chris Hudel for the implementation of this method. public static CertificateStore CreateFromPfxFile(byte[] file, string password, bool exportable, KeysetLocation location) { if (password == null || file == null) throw new ArgumentNullException("The arguments cannot be null references."); CertificateStore cs; DataBlob pPFX = new DataBlob(); // Crypt_data_blob contains two elements, // cbData = the size of the blob // pbData = a byte array of [cbData] size containing contents of the .p12 file pPFX.cbData = file.Length; // We need to marshal the byte array Bytes into a pointer so that it can be placed // in the structure (class) for the WinAPI call IntPtr buffer = Marshal.AllocHGlobal(file.Length); Marshal.Copy(file, 0, buffer, file.Length); pPFX.pbData = buffer; // IF this really is a valid PFX file, then do some work on it try { if (SspiProvider.PFXIsPFXBlob(ref pPFX) != 0) { if (SspiProvider.PFXVerifyPassword(ref pPFX, password, 0) != 0) { int flags = (int)location; if (exportable) flags |= SecurityConstants.CRYPT_EXPORTABLE; IntPtr m_Handle = SspiProvider.PFXImportCertStore(ref pPFX, password, flags); if (m_Handle.Equals(IntPtr.Zero)) { throw new CertificateException("Unable to import the PFX file! [error code = " + Marshal.GetLastWin32Error() + "]"); } cs = new CertificateStore(m_Handle); } else { throw new ArgumentException("The specified password is invalid."); } } else { throw new CertificateException("The specified file is not a PFX file."); } } finally { // Free the pointer Marshal.FreeHGlobal(buffer); } return cs; }
/// <summary> /// Initializes this <see cref="Certificate"/> instance from a handle. /// </summary> /// <param name="handle">The handle from which to initialize the state of the new instance.</param> /// <param name="duplicate"><b>true</b> if the handle should be duplicated, <b>false</b> otherwise.</param> /// <param name="store">The store that owns the certificate.</param> /// <exception cref="ArgumentException"><paramref name="handle"/> is invalid.</exception> private void InitCertificate(IntPtr handle, bool duplicate, CertificateStore store) { if (handle == IntPtr.Zero) throw new ArgumentException("Invalid certificate handle!"); if (duplicate) m_Handle = SspiProvider.CertDuplicateCertificateContext(handle); else m_Handle = handle; m_Context = (CertificateContext)Marshal.PtrToStructure(handle, typeof(CertificateContext)); m_CertInfo = (CertificateInfo)Marshal.PtrToStructure(m_Context.pCertInfo, typeof(CertificateInfo)); if (store == null) { m_Store = null; } else { m_Store = store; } }
private int TestMethods() { Certificate c = null; CertificateStore cs = null; try { c = CertificateStore.CreateFromCerFile(@"certs\server.base64.cer").FindCertificateByUsage(new string[] {"1.3.6.1.5.5.7.3.1"}); cs = new CertificateStore(); } catch { AddError("CS-TM-0"); return 1; } // AddCertificate + EnumCertificates try { cs.AddCertificate(null); AddError("CS-TM-1"); } catch (ArgumentNullException) { } catch { AddError("CS-TM-2"); } try { cs.AddCertificate(c); if (cs.EnumCertificates().Length != 1) AddError("CS-TM-3"); else if (!cs.EnumCertificates()[0].Equals(c)) AddError("CS-TM-4"); } catch { AddError("CS-TM-5"); } // DeleteCertificate + EnumCertificates try { cs.DeleteCertificate(null); AddError("CS-TM-6"); } catch (ArgumentNullException) { } catch { AddError("CS-TM-7"); } try { cs.DeleteCertificate(c); if (cs.EnumCertificates().Length != 0) AddError("CS-TM-8"); } catch { AddError("CS-TM-9"); } // CreateFromPfxFile try { cs.AddCertificate(c); CertificateStore cs2 = CertificateStore.CreateFromPfxFile(cs.ToPfxBuffer("test", true), "test"); if (cs2.EnumCertificates().Length != 1) AddError("CS-TM-10"); if (!c.Equals(cs2.EnumCertificates()[0])) AddError("CS-TM-11"); } catch { AddError("CS-TM-12"); } // FindCertificate and the CreateFrom*File methods are // already tested in other blackbox classes return 12; }