/// <summary> /// Searches for a certificate extension. /// </summary> /// <param name="oid">The extension to search for.</param> /// <returns>An instance of the <see cref="Extension"/> class -or- a null reference (<b>Nothing</b> in Visual Basic) if the specified extension could not be found.</returns> /// <exception cref="ArgumentNullException"><paramref name="oid"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> public Extension FindExtension(string oid) { if (oid == null) throw new ArgumentNullException(); IntPtr ret = SspiProvider.CertFindExtension(oid, m_CertInfo.cExtension.ToInt32(), m_CertInfo.rgExtension); if (ret == IntPtr.Zero) { return null; } else { CERT_EXTENSION ce = (CERT_EXTENSION)Marshal.PtrToStructure(ret, typeof(CERT_EXTENSION)); Extension ext = new Extension(Marshal.PtrToStringAnsi(ce.pszObjId), ce.fCritical != 0, new byte[ce.ValuecbData]); Marshal.Copy(ce.ValuepbData, ext.EncodedValue, 0, ce.ValuecbData); return ext; } }
/// <summary> /// Decodes the specified extension and returns an object of the specified type that is instantiated with the decoded bytes. /// </summary> /// <param name="extension">The certificate extension to decode.</param> /// <param name="oid">The Object Identifier of the structure. Refer to the documentation of the <a href="http://msdn.microsoft.com/library/en-us/security/security/cryptdecodeobject.asp">CryptDecodeObject</a> function for more information.</param> /// <param name="returnType">A <see cref="Type"/> instance. See remarks.</param> /// <returns>An object of the type <paramref name="returnType"/>.</returns> /// <remarks><p> /// The specified type should have a public constructor that takes an IntPtr and an int as parameters [in that order]. /// The IntPtr is a pointer to the decoded buffer and the int contains the number of decoded bytes. /// The type should not keep the IntPtr reference after construction of an instance, because the memory is freed when the DecodeExtension method returns. /// </p></remarks> /// <exception cref="ArgumentNullException">One of the parameters is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while decoding the certificate extension.</exception> public static object DecodeExtension(Extension extension, string oid, Type returnType) { if (oid == null) throw new ArgumentNullException("oid"); IntPtr buffer = Marshal.StringToHGlobalAnsi(oid); try { return DecodeExtension(extension, buffer, returnType); } finally { Marshal.FreeHGlobal(buffer); } }
/// <summary> /// Decodes the specified extension and returns an object of the specified type that is instantiated with the decoded bytes. /// </summary> /// <param name="extension">The certificate extension to decode.</param> /// <param name="oid">The Object Identifier of the structure.</param> /// <param name="returnType">A <see cref="Type"/> instance. See remarks.</param> /// <returns>An object of the type <paramref name="returnType"/>.</returns> /// <remarks><p> /// The specified type should have a public constructor that takes an IntPtr and an int as parameters [in that order]. /// The IntPtr is a pointer to the decoded buffer and the int contains the number of decoded bytes. /// The type should not keep the IntPtr reference after construction of an instance, because the memory is freed when the DecodeExtension method returns. /// </p></remarks> /// <exception cref="ArgumentNullException">One of the parameters is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while decoding the certificate extension.</exception> protected static object DecodeExtension(Extension extension, IntPtr oid, Type returnType) { if (extension.EncodedValue == null || returnType == null) throw new ArgumentNullException(); int size = 0; if (SspiProvider.CryptDecodeObject(SecurityConstants.PKCS_7_ASN_ENCODING | SecurityConstants.X509_ASN_ENCODING, oid, extension.EncodedValue, extension.EncodedValue.Length, 0, IntPtr.Zero, ref size) == 0) throw new CertificateException("Could not decode the extension."); IntPtr buffer = Marshal.AllocHGlobal(size); try { if (SspiProvider.CryptDecodeObject(SecurityConstants.PKCS_7_ASN_ENCODING | SecurityConstants.X509_ASN_ENCODING, oid, extension.EncodedValue, extension.EncodedValue.Length, 0, buffer, ref size) == 0) throw new CertificateException("Could not decode the extension."); return Activator.CreateInstance(returnType, new object[] { buffer, size }); } catch (CertificateException ce) { throw ce; } catch (Exception e) { throw new CertificateException("Unable to instantiate the specified object type.", e); } finally { Marshal.FreeHGlobal(buffer); } }
/// <summary> /// Decodes the specified extension and returns an object of the specified type that is instantiated with the decoded bytes. /// </summary> /// <param name="extension">The certificate extension to decode.</param> /// <param name="oid">One of the predefined constants specified in the Win32 CryptoAPI. Refer to the documentation of the <a href="http://msdn.microsoft.com/library/en-us/security/security/cryptdecodeobject.asp">CryptDecodeObject</a> function for more information.</param> /// <param name="returnType">A <see cref="Type"/> instance. See remarks.</param> /// <returns>An object of the type <paramref name="returnType"/>.</returns> /// <remarks><p> /// The specified type should have a public constructor that takes an IntPtr and an int as parameters [in that order]. /// The IntPtr is a pointer to the decoded buffer and the int contains the number of decoded bytes. /// The type should not keep the IntPtr reference after construction of an instance, because the memory is freed when the DecodeExtension method returns. /// </p></remarks> /// <exception cref="ArgumentNullException">One of the parameters is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while decoding the certificate extension.</exception> public static object DecodeExtension(Extension extension, int oid, Type returnType) { return DecodeExtension(extension, new IntPtr(oid), returnType); }
/// <summary> /// Returns a list of extensions of the X.509v3 certificate. /// </summary> /// <returns>An array of Extension instances.</returns> public Extension[] GetExtensions() { int len = m_CertInfo.cExtension.ToInt32(); Extension[] ret = new Extension[len]; int extSize = 8 + IntPtr.Size * 2; IntPtr ptr = m_CertInfo.rgExtension; Type cest = typeof(CERT_EXTENSION); CERT_EXTENSION ce; for (int i = 0; i < len; i++) { ce = (CERT_EXTENSION)Marshal.PtrToStructure(ptr, cest); ret[i] = new Extension(Marshal.PtrToStringAnsi(ce.pszObjId), ce.fCritical != 0, new byte[ce.ValuecbData]); Marshal.Copy(ce.ValuepbData, ret[i].EncodedValue, 0, ce.ValuecbData); ptr = new IntPtr(ptr.ToInt64() + extSize); } return ret; }