Return refreshed handle on GetHandle()
authorKyungwook Tak <k.tak@samsung.com>
Mon, 7 Nov 2016 06:05:49 +0000 (15:05 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Mon, 7 Nov 2016 06:14:30 +0000 (15:14 +0900)
Properties can be changed after IntPtr handle allocated so handle always
retrieved from latest properties

Change-Id: Ie2c68e5618f0363115d0819e02214ca97e66a472
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Certificate.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/CertificateManager.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Key.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/Pkcs12.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeAliasListHandle.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeCertificateListHandle.cs
Tizen.Security.SecureRepository/Tizen.Security.SecureRepository/SafeRawBufferHandle.cs

index e7bfdd2..f71bd14 100755 (executable)
@@ -30,13 +30,17 @@ namespace Tizen.Security.SecureRepository
         /// </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);
         }
@@ -48,33 +52,51 @@ namespace Tizen.Security.SecureRepository
         /// <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>
@@ -95,8 +117,10 @@ namespace Tizen.Security.SecureRepository
 
         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>
@@ -104,16 +128,17 @@ namespace Tizen.Security.SecureRepository
         /// </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;
         }
index acb3cfd..c2b570b 100644 (file)
@@ -95,7 +95,7 @@ namespace Tizen.Security.SecureRepository
             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");
 
@@ -128,8 +128,8 @@ namespace Tizen.Security.SecureRepository
             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");
 
@@ -149,7 +149,7 @@ namespace Tizen.Security.SecureRepository
         {
             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;
         }
index 577b823..6da8479 100755 (executable)
@@ -26,43 +26,66 @@ namespace Tizen.Security.SecureRepository
     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>
@@ -91,11 +114,11 @@ namespace Tizen.Security.SecureRepository
 
         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>
@@ -103,16 +126,17 @@ namespace Tizen.Security.SecureRepository
         /// </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;
         }
index acfc3e4..27ecf2f 100755 (executable)
@@ -44,7 +44,7 @@ namespace Tizen.Security.SecureRepository
         /// </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);
@@ -101,29 +101,17 @@ namespace Tizen.Security.SecureRepository
             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");
@@ -193,7 +181,7 @@ namespace Tizen.Security.SecureRepository
         /// </summary>
         public override bool IsInvalid
         {
-            get { return handle == IntPtr.Zero; }
+            get { return this.handle == IntPtr.Zero; }
         }
 
         /// <summary>
@@ -203,7 +191,7 @@ namespace Tizen.Security.SecureRepository
         /// <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;
         }
index a6f12ab..fa93b97 100755 (executable)
@@ -23,16 +23,16 @@ namespace Tizen.Security.SecureRepository
 {
     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;
@@ -48,16 +48,17 @@ namespace Tizen.Security.SecureRepository
         /// </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;
         }
index d36092a..94412d5 100755 (executable)
@@ -25,26 +25,25 @@ namespace Tizen.Security.SecureRepository
     {
         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
@@ -52,44 +51,60 @@ namespace Tizen.Security.SecureRepository
             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>
@@ -97,16 +112,17 @@ namespace Tizen.Security.SecureRepository
         /// </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;
         }
index 66fa93e..d558ba1 100644 (file)
@@ -22,28 +22,45 @@ namespace Tizen.Security.SecureRepository
 {
     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>
@@ -51,16 +68,17 @@ namespace Tizen.Security.SecureRepository
         /// </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;
         }