/// <summary> /// Creates a new certificate store from a PFX/P12 encoded file. /// </summary> /// <param name="file">The full path to the 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="IOException">An error occurs whil reading from the specified file.</exception> /// <exception cref="CertificateException">An error occurs while loading the PFX file.</exception> /// <exception cref="ArgumentException"><paramref name="password"/> is invalid.</exception> public static CertificateStore CreateFromPfxFile(string file, string password, bool exportable, KeysetLocation location) { return CreateFromPfxFile(GetFileContents(file), password, exportable, location); }
/// <summary> /// Creates a new instance of the <see cref="Certificate"/> class by opening a PFX file and retrieving the first certificate from it. /// </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>One of the certificates in the PFX file.</returns> /// <exception cref="ArgumentNullException"><paramref name="file"/> or <paramref name="password"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while loading certificates from the specified bytes.</exception> /// <exception cref="ArgumentException"><paramref name="password"/> is invalid.</exception> /// <remarks> /// Warning: this method returns the first Certificate it can find in the specified PFX file. /// Care should be taken to verify whether the correct Certificate instance is returned /// when using PFX files that contain more than one certificate. /// For more fine-grained control over which certificate is returned, use /// the CertificateStore.CreateFromPfxFile method to instantiate a CertificateStore object /// and then use the CertificateStore.FindCertificateBy*** methods. /// </remarks> public static Certificate CreateFromPfxFile(byte[] file, string password, bool exportable, KeysetLocation location) { return CertificateStore.CreateFromPfxFile(file, password, exportable, location).FindCertificate(); }
/// <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; }