/// </summary>
/// <param name="filePath">The path of certificate file to be loaded.</param>
/// <returns>Loaded certificate class instance.</returns>
- /// <exception cref="InvalidOperationException">Invalid certificate file format. Provided file path does not exist or cannot be accessed.</exception>
+ /// <exception cref="InvalidOperationException">
+ /// Invalid certificate file format. Provided file path does not exist or
+ /// cannot be accessed.
+ /// </exception>
static public Certificate Load(string filePath)
{
- IntPtr ptr = new IntPtr();
+ IntPtr ptr = IntPtr.Zero;
- int ret = Interop.CkmcTypes.LoadCertFromFile(filePath, out ptr);
- Interop.CheckNThrowException(ret, "Failed to load Certificate. file=" + filePath);
+ Interop.CheckNThrowException(
+ CkmcTypes.LoadCertFromFile(filePath, out ptr),
+ "Failed to load Certificate: " + filePath);
return new Certificate(ptr);
}
/// <param name="format">The format of the binary data.</param>
public Certificate(byte[] binary, DataFormat format) : base(IntPtr.Zero, true)
{
- this.SetHandle(IntPtr.Zero);
- Binary = binary;
- Format = format;
+ this.Binary = binary;
+ this.Format = format;
}
- internal Certificate(IntPtr ptrCkmcCert, bool ownsHandle = true) : base(IntPtr.Zero, ownsHandle)
+ internal Certificate(IntPtr ptr, bool ownsHandle = true) :
+ base(ptr, ownsHandle)
{
- base.SetHandle(ptrCkmcCert);
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
- CkmcCert ckmcCert = Marshal.PtrToStructure<CkmcCert>(ptrCkmcCert);
- Binary = new byte[(int)ckmcCert.size];
- Marshal.Copy(ckmcCert.rawCert, Binary, 0, Binary.Length);
- Format = (DataFormat)ckmcCert.dataFormat;
+ var ckmcCert = Marshal.PtrToStructure<CkmcCert>(ptr);
+ this.Binary = new byte[(int)ckmcCert.size];
+ Marshal.Copy(ckmcCert.rawCert, this.Binary, 0, this.Binary.Length);
+ this.Format = (DataFormat)ckmcCert.dataFormat;
}
- internal IntPtr GetHandle()
+ // Refresh handle(IntPtr) always. Because C# layer
+ // properties(Binary, Format) could be changed.
+ internal IntPtr GetHandle(bool updateHandle = true)
{
- if (this.handle == IntPtr.Zero)
+ IntPtr ptr = IntPtr.Zero;
+ try
{
- int ret = Interop.CkmcTypes.CertNew(this.Binary,
- (UIntPtr)this.Binary.Length,
- (int)this.Format,
- out this.handle);
- Interop.CheckNThrowException(ret, "Failed to create cert");
+ int ret = CkmcTypes.CertNew(
+ this.Binary, (UIntPtr)this.Binary.Length, (int)this.Format, out ptr);
+ CheckNThrowException(ret, "Failed to create cert");
+
+ if (updateHandle)
+ {
+ if (!this.IsInvalid && !this.ReleaseHandle())
+ throw new InvalidOperationException(
+ "Failed to release cert handle");
+
+ this.SetHandle(ptr);
+ }
+
+ return ptr;
}
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ CkmcTypes.CertFree(ptr);
- return this.handle;
+ throw;
+ }
}
/// <summary>
internal CkmcCert ToCkmcCert()
{
- byte[] bin = (Binary != null) ? Binary : new byte[0];
- return new Interop.CkmcCert(new PinnedObject(bin), bin.Length, (int)Format);
+ return new Interop.CkmcCert(
+ (Binary == null) ? IntPtr.Zero : new PinnedObject(this.Binary),
+ (Binary == null) ? 0 : this.Binary.Length,
+ (int)Format);
}
/// <summary>
/// </summary>
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
- /// When overridden in a derived class, executes the code required to free the handle.
+ /// When overridden in a derived class, executes the code required to free
+ /// the handle.
/// </summary>
/// <returns>true if the handle is released successfully.</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.CertFree(handle);
+ Interop.CkmcTypes.CertFree(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}
var untrustedCerts = new SafeCertificateListHandle(untrustedCertificates);
int ret = Interop.CkmcManager.GetCertChain(certificate.GetHandle(),
- untrustedCerts.ToCkmcCertificateListPtr(),
+ untrustedCerts.GetHandle(),
out ptrCertChain);
Interop.CheckNThrowException(ret, "Failed to get certificate chain");
var trustedCerts = new SafeCertificateListHandle(trustedCertificates);
int ret = Interop.CkmcManager.GetCertChainWithTrustedCerts(
- certificate.GetHandle(), untrustedCerts.ToCkmcCertificateListPtr(),
- trustedCerts.ToCkmcCertificateListPtr(), useTrustedSystemCertificates,
+ certificate.GetHandle(), untrustedCerts.GetHandle(),
+ trustedCerts.GetHandle(), useTrustedSystemCertificates,
out ptrCertChain);
Interop.CheckNThrowException(ret, "Failed to get certificate chain with trusted certificates");
{
int ocspStatus = (int)OcspStatus.Good;
SafeCertificateListHandle certChain = new SafeCertificateListHandle(certificateChain);
- int ret = Interop.CkmcManager.OcspCheck(certChain.ToCkmcCertificateListPtr(), ref ocspStatus);
+ int ret = Interop.CkmcManager.OcspCheck(certChain.GetHandle(), ref ocspStatus);
Interop.CheckNThrowException(ret, "Failed to get certificate chain with trusted certificates");
return (OcspStatus)ocspStatus;
}
public class Key : SafeHandle
{
/// <summary>
- /// A constructor of Key that takes the binary, its type, and optional password of binary.
+ /// A constructor of Key that takes the binary, its type, and optional password
+ /// of binary.
/// </summary>
- /// <param name="binary">The binary value of a key. This binary may be encrypted with binaryPassword.</param>
+ /// <param name="binary">
+ /// The binary value of a key. This binary may be encrypted with binaryPassword.
+ /// </param>
/// <param name="type">The key's type.</param>
- /// <param name="binaryPassword">The password used to decrypt binary when binary is encrypted.</param>
- public Key(byte[] binary, KeyType type, string binaryPassword) : base(IntPtr.Zero, true)
+ /// <param name="binaryPassword">
+ /// The password used to decrypt binary when binary is encrypted.
+ /// </param>
+ public Key(byte[] binary, KeyType type, string binaryPassword) :
+ base(IntPtr.Zero, true)
{
- this.SetHandle(IntPtr.Zero);
- Binary = binary;
- Type = type;
- BinaryPassword = binaryPassword;
+ this.Binary = binary;
+ this.Type = type;
+ this.BinaryPassword = binaryPassword;
}
- internal Key(IntPtr ptr, bool ownsHandle = true) : base(IntPtr.Zero, ownsHandle)
+ internal Key(IntPtr ptr, bool ownsHandle = true) : base(ptr, ownsHandle)
{
- base.SetHandle(ptr);
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
- CkmcKey ckmcKey = Marshal.PtrToStructure<CkmcKey>(handle);
- Binary = new byte[(int)ckmcKey.size];
- Marshal.Copy(ckmcKey.rawKey, Binary, 0, Binary.Length);
- Type = (KeyType)ckmcKey.keyType;
- BinaryPassword = ckmcKey.password;
+ var ckmcKey = Marshal.PtrToStructure<CkmcKey>(ptr);
+ this.Binary = new byte[(int)ckmcKey.size];
+ Marshal.Copy(ckmcKey.rawKey, this.Binary, 0, this.Binary.Length);
+ this.Type = (KeyType)ckmcKey.keyType;
+ this.BinaryPassword = ckmcKey.password;
}
- internal IntPtr GetHandle()
+ // Refresh handle(IntPtr) always. Because C# layer
+ // properties(Binary, Type, BinaryPassword) could be changed.
+ internal IntPtr GetHandle(bool updateHandle = true)
{
- if (this.handle == IntPtr.Zero)
+ IntPtr ptr = IntPtr.Zero;
+ try
{
- int ret = Interop.CkmcTypes.KeyNew(this.Binary,
- (UIntPtr)this.Binary.Length,
- (int)this.Type,
- this.BinaryPassword,
- out this.handle);
- Interop.CheckNThrowException(ret, "Failed to create key");
+ int ret = Interop.CkmcTypes.KeyNew(
+ this.Binary, (UIntPtr)this.Binary.Length, (int)this.Type,
+ this.BinaryPassword, out ptr);
+ CheckNThrowException(ret, "Failed to create key");
+
+ if (updateHandle)
+ {
+ if (!this.IsInvalid && !this.ReleaseHandle())
+ throw new InvalidOperationException(
+ "Failed to release key handle");
+
+ this.SetHandle(ptr);
+ }
+
+ return ptr;
}
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.KeyFree(ptr);
- return this.handle;
+ throw;
+ }
}
/// <summary>
internal CkmcKey ToCkmcKey()
{
- byte[] bin = (Binary != null) ? Binary : new byte[0] ;
- return new Interop.CkmcKey(new PinnedObject(bin),
- bin.Length,
- (int)Type,
- BinaryPassword);
+ return new Interop.CkmcKey(
+ (Binary == null) ? IntPtr.Zero : new PinnedObject(this.Binary),
+ (Binary == null) ? 0 : this.Binary.Length,
+ (int)this.Type,
+ this.BinaryPassword);
}
/// <summary>
/// </summary>
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
- /// When overridden in a derived class, executes the code required to free the handle.
+ /// When overridden in a derived class, executes the code required to free
+ /// the handle.
/// </summary>
/// <returns>true if the handle is released successfully</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.KeyFree(handle);
+ Interop.CkmcTypes.KeyFree(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}
/// </exception>
static public Pkcs12 Load(string filePath, string filePassword)
{
- IntPtr ptr = new IntPtr();
+ IntPtr ptr = IntPtr.Zero;
int ret = Interop.CkmcTypes.Pkcs12Load(filePath, filePassword, out ptr);
Interop.CheckNThrowException(ret, "Failed to load PKCS12. file=" + filePath);
IntPtr p12Ptr = IntPtr.Zero;
try
{
- int ret = Interop.CkmcTypes.KeyNew(
- this.PrivateKey.Binary, (UIntPtr)this.PrivateKey.Binary.Length,
- (int)this.PrivateKey.Type, this.PrivateKey.BinaryPassword, out keyPtr);
- Interop.CheckNThrowException(ret, "Failed to duplicate key");
+ keyPtr = this.PrivateKey.GetHandle(false);
if (this.Certificate != null)
- {
- ret = Interop.CkmcTypes.CertNew(
- this.Certificate.Binary, (UIntPtr)this.Certificate.Binary.Length,
- (int)this.Certificate.Format, out certPtr);
- Interop.CheckNThrowException(ret, "Failed to duplicate cert");
- }
+ certPtr = this.Certificate.GetHandle(false);
- if (this.CaChain != null)
- {
- var safeCertsHandle = new SafeCertificateListHandle(this.CaChain);
- // handle should not be updated in SafeCertificateListHandle
- // because it'll be freed with Pkcs12Free
- cacertPtr = safeCertsHandle.ToCkmcCertificateListPtr(false);
- }
+ if (this._certChainHandle != null)
+ cacertPtr = this._certChainHandle.GetHandle(false);
- ret = Interop.CkmcTypes.Pkcs12New(keyPtr, certPtr, cacertPtr, out p12Ptr);
- Interop.CheckNThrowException(ret, "Failed to create pkcs12");
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.Pkcs12New(keyPtr, certPtr, cacertPtr, out p12Ptr),
+ "Failed to create pkcs12");
if (!this.IsInvalid && !this.ReleaseHandle())
throw new InvalidOperationException("Failed to release p12 handle");
/// </summary>
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
/// <returns>true if the handle is released successfully</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.Pkcs12Free(handle);
+ Interop.CkmcTypes.Pkcs12Free(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}
{
internal class SafeAliasListHandle : SafeHandle
{
- public SafeAliasListHandle(IntPtr ptrAliases, bool ownsHandle = true) : base(IntPtr.Zero, ownsHandle)
+ public SafeAliasListHandle(IntPtr ptr, bool ownsHandle = true) :
+ base(ptr, ownsHandle)
{
- base.SetHandle(ptrAliases);
-
- List<string> aliases = new List<string>();
- while (ptrAliases != IntPtr.Zero)
+ var cur = ptr;
+ var aliases = new List<string>();
+ while (cur != IntPtr.Zero)
{
- CkmcAliasList ckmcAliasList = Marshal.PtrToStructure<CkmcAliasList>(ptrAliases);
+ var ckmcAliasList = Marshal.PtrToStructure<CkmcAliasList>(cur);
aliases.Add(Marshal.PtrToStringAnsi(ckmcAliasList.alias));
- ptrAliases = ckmcAliasList.next;
+ cur = ckmcAliasList.next;
}
this.Aliases = aliases;
/// </summary>
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
- /// When overridden in a derived class, executes the code required to free the handle.
+ /// When overridden in a derived class, executes the code required to free
+ /// the handle.
/// </summary>
/// <returns>true if the handle is released successfully</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.AliasListAllFree(handle);
+ Interop.CkmcTypes.AliasListAllFree(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}
{
private IEnumerable<Certificate> _certificates;
- public SafeCertificateListHandle(IEnumerable<Certificate> certs) : base(IntPtr.Zero, true)
+ public SafeCertificateListHandle(IEnumerable<Certificate> certs) :
+ base(IntPtr.Zero, true)
{
- this.SetHandle(IntPtr.Zero);
_certificates = certs;
}
- public SafeCertificateListHandle(IntPtr ptrCerts, bool ownsHandle = true) : base(IntPtr.Zero, ownsHandle)
+ public SafeCertificateListHandle(IntPtr ptr, bool ownsHandle = true) :
+ base(ptr, ownsHandle)
{
- this.SetHandle(ptrCerts);
-
- List<Certificate> certs = new List<Certificate>();
- IntPtr ptrCurr = handle;
- while (ptrCurr != IntPtr.Zero)
+ var cur = ptr;
+ var certs = new List<Certificate>();
+ while (cur != IntPtr.Zero)
{
- CkmcCertList ckmcCertList = Marshal.PtrToStructure<CkmcCertList>(ptrCurr);
+ var ckmcCertList = Marshal.PtrToStructure<CkmcCertList>(cur);
certs.Add(new Certificate(ckmcCertList.cert, false));
- ptrCurr = ckmcCertList.next;
+ cur = ckmcCertList.next;
}
- _certificates = certs;
+ this._certificates = certs;
}
public IEnumerable<Certificate> Certificates
get { return _certificates; }
}
- internal IntPtr ToCkmcCertificateListPtr(bool updateHandle = true)
+ internal IntPtr GetHandle(bool updateHandle = true)
{
if (_certificates == null)
return IntPtr.Zero;
if (!IsInvalid)
- return handle;
+ return this.handle;
IntPtr first = IntPtr.Zero;
IntPtr previous = IntPtr.Zero;
+ IntPtr certPtr = IntPtr.Zero;
- int ret;
- foreach (Certificate cert in _certificates)
+ try
{
- IntPtr certPtr;
- ret = Interop.CkmcTypes.CertNew(cert.Binary, (UIntPtr)cert.Binary.Length, (int)cert.Format, out certPtr);
- Interop.CheckNThrowException(ret, "Failed to create new Certificate.");
-
- IntPtr outCertList;
- if (previous == IntPtr.Zero)
- {
- ret = Interop.CkmcTypes.CertListNew(certPtr, out outCertList);
- Interop.CheckNThrowException(ret, "Failed to create new CertificateList.");
- first = outCertList;
- previous = outCertList;
- }
- else
+ foreach (var cert in this._certificates)
{
- ret = Interop.CkmcTypes.CertListAdd(previous, certPtr, out outCertList);
- Interop.CheckNThrowException(ret, "Failed to add Certificate to CertificateList.");
+ // initialize local variables to release memory safely for
+ // in case of exception occured
+ certPtr = IntPtr.Zero;
+
+ certPtr = cert.GetHandle(false);
+
+ IntPtr outCertList;
+ if (previous == IntPtr.Zero)
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.CertListNew(certPtr, out outCertList),
+ "Failed to create new CertificateList.");
+ first = outCertList;
+ }
+ else
+ {
+ Interop.CheckNThrowException(
+ Interop.CkmcTypes.CertListAdd(previous, certPtr,
+ out outCertList),
+ "Failed to add Certificate to CertificateList.");
+ }
previous = outCertList;
}
- }
- if (updateHandle)
- this.SetHandle(first);
+ if (updateHandle)
+ this.SetHandle(first);
+
+ return first;
+ }
+ catch
+ {
+ if (first != IntPtr.Zero)
+ Interop.CkmcTypes.CertListAllFree(this.handle);
+ if (certPtr != IntPtr.Zero)
+ Interop.CkmcTypes.CertFree(certPtr);
- return first;
+ throw;
+ }
}
/// <summary>
/// </summary>
public override bool IsInvalid
{
- get { return (handle == IntPtr.Zero); }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
- /// When overridden in a derived class, executes the code required to free the handle.
+ /// When overridden in a derived class, executes the code required to free
+ /// the handle.
/// </summary>
/// <returns>true if the handle is released successfully</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.CertListAllFree(handle);
+ Interop.CkmcTypes.CertListAllFree(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}
{
internal class SafeRawBufferHandle : SafeHandle
{
- public SafeRawBufferHandle(IntPtr ptrRawBuffer, bool ownsHandle = true) : base(IntPtr.Zero, true)
+ public SafeRawBufferHandle(IntPtr ptr, bool ownsHandle = true) :
+ base(ptr, true)
{
- this.SetHandle(ptrRawBuffer);
-
- if (ptrRawBuffer == IntPtr.Zero)
- return;
-
- CkmcRawBuffer buff = Marshal.PtrToStructure<CkmcRawBuffer>(ptrRawBuffer);
- byte[] data = new byte[(int)buff.size];
- Marshal.Copy(buff.data, data, 0, data.Length);
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("Returned ptr from CAPI cannot be null");
+ var ckmcBuf = Marshal.PtrToStructure<CkmcRawBuffer>(ptr);
+ byte[] data = new byte[(int)ckmcBuf.size];
+ Marshal.Copy(ckmcBuf.data, data, 0, data.Length);
this.Data = data;
}
- public byte[] Data
+ internal IntPtr GetHandle()
{
- get; set;
+ IntPtr ptr = IntPtr.Zero;
+ try
+ {
+ int ret = Interop.CkmcTypes.BufferNew(
+ this.Data, (UIntPtr)this.Data.Length, out ptr);
+ CheckNThrowException(ret, "Failed to create buf");
+
+ if (!this.IsInvalid && !this.ReleaseHandle())
+ throw new InvalidOperationException("Failed to release buf handle");
+
+ this.SetHandle(ptr);
+ return this.handle;
+ }
+ catch
+ {
+ if (ptr != IntPtr.Zero)
+ Interop.CkmcTypes.BufferFree(ptr);
+
+ throw;
+ }
}
- internal IntPtr GetHandle()
+ public byte[] Data
{
- return this.handle;
+ get; set;
}
/// <summary>
/// </summary>
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
/// <summary>
- /// When overridden in a derived class, executes the code required to free the handle.
+ /// When overridden in a derived class, executes the code required to free
+ /// the handle.
/// </summary>
/// <returns>true if the handle is released successfully</returns>
protected override bool ReleaseHandle()
{
- Interop.CkmcTypes.BufferFree(handle);
+ Interop.CkmcTypes.BufferFree(this.handle);
this.SetHandle(IntPtr.Zero);
return true;
}