security: Signature interface change and initial fixes for OSX private key store

Change-Id: Ic6d074e99346c4bf9d7b2c20c961dd01d770636d
diff --git a/src/security/identity/identity-manager.cpp b/src/security/identity/identity-manager.cpp
index 1befdcd..ce6ff21 100644
--- a/src/security/identity/identity-manager.cpp
+++ b/src/security/identity/identity-manager.cpp
@@ -228,9 +228,10 @@
 
   SignatureSha256WithRsa signature;
   signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
-
+  
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  signature.setValue(tpm().sign(buffer, bufferLength, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  signature.setValue
+    (tpm().sign(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
   return signature;
 }
 
@@ -243,10 +244,10 @@
 
   SignatureSha256WithRsa signature;
   signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+  data.setSignature(signature);
 
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  signature.setValue(tpm().sign(data, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
-  data.setSignature(signature);
+  tpm().sign(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
 }
 
 void
@@ -254,10 +255,10 @@
 {
   SignatureSha256WithRsa signature;
   signature.setKeyLocator(certificate.getName().getPrefix(-1));
+  data.setSignature(signature);
 
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  signature.setValue(tpm().sign(data, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
-  data.setSignature(signature);
+  tpm().sign(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
 }
 
 void
@@ -265,10 +266,10 @@
 {
   SignatureSha256WithRsa signature;
   signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
+  cert.setSignature(signature);
 
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  signature.setValue(tpm().sign(cert, signature, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
-  cert.setSignature(signature);
+  tpm().sign(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
 }
 
 Name
diff --git a/src/security/identity/memory-private-key-storage.cpp b/src/security/identity/memory-private-key-storage.cpp
index 7c3a2e0..1394126 100644
--- a/src/security/identity/memory-private-key-storage.cpp
+++ b/src/security/identity/memory-private-key-storage.cpp
@@ -5,26 +5,56 @@
  * See COPYING for copyright and distribution information.
  */
 
-#if 1
-#include <stdexcept>
-#endif
-#include "../../c/util/crypto.h"
-#include <ndn-cpp/security/security-exception.hpp>
-#include <ndn-cpp/security/identity/memory-private-key-storage.hpp>
+#include "memory-private-key-storage.hpp"
+#include "../certificate/public-key.hpp"
+#include <openssl/ssl.h>
+#include <openssl/sha.h>
+#include <openssl/rsa.h>
 
 using namespace std;
 
 namespace ndn {
 
+/**
+ * RsaPrivateKey is a simple class to hold an RSA private key.
+ */
+class MemoryPrivateKeyStorage::RsaPrivateKey {
+public:
+  RsaPrivateKey(const uint8_t *keyDer, size_t keyDerLength)
+  {
+    // Use a temporary pointer since d2i updates it.
+    const uint8_t *derPointer = keyDer;
+    privateKey_ = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
+    if (!privateKey_)
+      throw Error("RsaPrivateKey constructor: Error decoding private key DER");
+  }
+    
+  ~RsaPrivateKey()
+  {
+    if (privateKey_)
+      RSA_free(privateKey_);
+  }
+    
+  rsa_st *
+  getPrivateKey()
+  {
+    return privateKey_;
+  }
+    
+private:
+  rsa_st * privateKey_;
+};
+
 MemoryPrivateKeyStorage::~MemoryPrivateKeyStorage()
 {
 }
 
-void MemoryPrivateKeyStorage::setKeyPairForKeyName
-  (const Name& keyName, uint8_t *publicKeyDer, size_t publicKeyDerLength, uint8_t *privateKeyDer, 
-   size_t privateKeyDerLength)
+void
+MemoryPrivateKeyStorage::setKeyPairForKeyName(const Name& keyName,
+                                              uint8_t *publicKeyDer, size_t publicKeyDerLength,
+                                              uint8_t *privateKeyDer, size_t privateKeyDerLength)
 {
-  publicKeyStore_[keyName.toUri()] = PublicKey::fromDer(Blob(publicKeyDer, publicKeyDerLength));
+  publicKeyStore_[keyName.toUri()]  = ptr_lib::make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
   privateKeyStore_[keyName.toUri()] = ptr_lib::make_shared<RsaPrivateKey>(privateKeyDer, privateKeyDerLength);
 }
 
@@ -32,54 +62,105 @@
 MemoryPrivateKeyStorage::generateKeyPair(const Name& keyName, KeyType keyType, int keySize)
 {
 #if 1
-  throw runtime_error("MemoryPrivateKeyStorage::generateKeyPair not implemented");
+  throw Error("MemoryPrivateKeyStorage::generateKeyPair not implemented");
 #endif
 }
 
 ptr_lib::shared_ptr<PublicKey> 
 MemoryPrivateKeyStorage::getPublicKey(const Name& keyName)
 {
-  map<string, ptr_lib::shared_ptr<PublicKey> >::iterator publicKey = publicKeyStore_.find(keyName.toUri());
+  PublicKeyStore::iterator publicKey = publicKeyStore_.find(keyName.toUri());
   if (publicKey == publicKeyStore_.end())
-    throw SecurityException(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
+    throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
   return publicKey->second;
 }
 
-Blob 
-MemoryPrivateKeyStorage::sign(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm)
+Block 
+MemoryPrivateKeyStorage::sign(const uint8_t *data, size_t dataLength,
+                              const Name& keyName,
+                              DigestAlgorithm digestAlgorithm)
 {
   if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
-    return Blob();
+    return ConstBufferPtr();
 
-  uint8_t digest[SHA256_DIGEST_LENGTH];
-  ndn_digestSha256(data, dataLength, digest);
-  // TODO: use RSA_size to get the proper size of the signature buffer.
-  uint8_t signatureBits[1000];
-  unsigned int signatureBitsLength;
-  
   // Find the private key and sign.
-  map<string, ptr_lib::shared_ptr<RsaPrivateKey> >::iterator privateKey = privateKeyStore_.find(keyName.toUri());
+  PrivateKeyStore::iterator privateKey = privateKeyStore_.find(keyName.toUri());
   if (privateKey == privateKeyStore_.end())
-    throw SecurityException(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
-  if (!RSA_sign(NID_sha256, digest, sizeof(digest), signatureBits, &signatureBitsLength, privateKey->second->getPrivateKey()))
-    throw SecurityException("Error in RSA_sign");
+    throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
   
-  return Blob(signatureBits, (size_t)signatureBitsLength);
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256_CTX sha256;
+  SHA256_Init(&sha256);
+  SHA256_Update(&sha256, data, dataLength);
+  SHA256_Final(digest, &sha256);
+
+  BufferPtr signatureBuffer = ptr_lib::make_shared<Buffer>();
+  signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
+  
+  unsigned int signatureBitsLength;  
+  if (!RSA_sign(NID_sha256, digest, sizeof(digest),
+                signatureBuffer->buf(),
+                &signatureBitsLength,
+                privateKey->second->getPrivateKey()))
+    {
+      throw Error("Error in RSA_sign");
+    }
+
+  return Block(Tlv::SignatureValue, signatureBuffer);
 }
 
-Blob 
+void
+MemoryPrivateKeyStorage::sign(Data &d,
+                              const Name& keyName,
+                              DigestAlgorithm digestAlgorithm)
+{
+  if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
+    Error("MemoryPrivateKeyStorage::sign only SHA256 digest is supported");
+
+  // Find the private key and sign.
+  PrivateKeyStore::iterator privateKey = privateKeyStore_.find(keyName.toUri());
+  if (privateKey == privateKeyStore_.end())
+    throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
+  
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256_CTX sha256;
+  SHA256_Init(&sha256);
+
+  SHA256_Update(&sha256, d.getName().    wireEncode().wire(), d.getName().    wireEncode().size());
+  SHA256_Update(&sha256, d.getMetaInfo().wireEncode().wire(), d.getMetaInfo().wireEncode().size());
+  SHA256_Update(&sha256, d.getContent().              wire(), d.getContent().              size());
+  SHA256_Update(&sha256, d.getSignature().getInfo().  wire(), d.getSignature().getInfo().  size());
+  
+  SHA256_Final(digest, &sha256);
+
+  BufferPtr signatureBuffer = ptr_lib::make_shared<Buffer>();
+  signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
+  
+  unsigned int signatureBitsLength;  
+  if (!RSA_sign(NID_sha256, digest, sizeof(digest),
+                signatureBuffer->buf(),
+                &signatureBitsLength,
+                privateKey->second->getPrivateKey()))
+    {
+      throw Error("Error in RSA_sign");
+    }
+
+  d.setSignatureValue(Block(Tlv::SignatureValue, signatureBuffer));
+}
+
+ConstBufferPtr
 MemoryPrivateKeyStorage::decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric)
 {
 #if 1
-  throw runtime_error("MemoryPrivateKeyStorage::decrypt not implemented");
+  throw Error("MemoryPrivateKeyStorage::decrypt not implemented");
 #endif
 }
 
-Blob
+ConstBufferPtr
 MemoryPrivateKeyStorage::encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric)
 {
 #if 1
-  throw runtime_error("MemoryPrivateKeyStorage::encrypt not implemented");
+  throw Error("MemoryPrivateKeyStorage::encrypt not implemented");
 #endif
 }
 
@@ -87,7 +168,7 @@
 MemoryPrivateKeyStorage::generateKey(const Name& keyName, KeyType keyType, int keySize)
 {
 #if 1
-  throw runtime_error("MemoryPrivateKeyStorage::generateKey not implemented");
+  throw Error("MemoryPrivateKeyStorage::generateKey not implemented");
 #endif
 }
 
@@ -103,19 +184,4 @@
     return false;
 }
 
-MemoryPrivateKeyStorage::RsaPrivateKey::RsaPrivateKey(uint8_t *keyDer, size_t keyDerLength)
-{
-  // Use a temporary pointer since d2i updates it.
-  const uint8_t *derPointer = keyDer;
-  privateKey_ = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
-  if (!privateKey_)
-    throw SecurityException("RsaPrivateKey constructor: Error decoding private key DER");
-}
-
-MemoryPrivateKeyStorage::RsaPrivateKey::~RsaPrivateKey()
-{
-  if (privateKey_)
-    RSA_free(privateKey_);
-}
-
 }
diff --git a/src/security/identity/osx-private-key-storage.cpp b/src/security/identity/osx-private-key-storage.cpp
index e504616..f41f89f 100644
--- a/src/security/identity/osx-private-key-storage.cpp
+++ b/src/security/identity/osx-private-key-storage.cpp
@@ -11,11 +11,14 @@
 
 #include <fstream>
 #include <sstream>
-#include <CoreFoundation/CoreFoundation.h>
 
 #include "../../util/logging.hpp"
-#include <ndn-cpp/security/identity/osx-private-key-storage.hpp>
-#include <ndn-cpp/security/security-exception.hpp>
+#include "osx-private-key-storage.hpp"
+#include "../certificate/public-key.hpp"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <CoreServices/CoreServices.h>
 
 using namespace std;
 
@@ -23,31 +26,107 @@
 
 namespace ndn
 {
+  class OSXPrivateKeyStorage::Impl {
+  public:
+    Impl(const std::string &keychainName)
+      : keyChainName_ ("" == keychainName ?  "NDN.keychain" : keychainName)
+    {
+    }
+    
+    /**
+     * convert NDN name of a key to internal name of the key
+     * @param keyName the NDN name of the key
+     * @param keyClass the class of the key
+     * @return the internal key name
+     */
+    std::string 
+    toInternalKeyName(const Name & keyName, KeyClass keyClass);
+  
+    /**
+     * Get key
+     * @param keyName the name of the key
+     * @param keyClass the class of the key
+     * @returns pointer to the key
+     */
+    SecKeychainItemRef 
+    getKey(const Name & keyName, KeyClass keyClass);
+        
+    /**
+     * convert keyType to MAC OS symmetric key key type
+     * @param keyType
+     * @returns MAC OS key type
+     */
+    const CFTypeRef 
+    getSymKeyType(KeyType keyType);
+  
+    /**
+     * convert keyType to MAC OS asymmetirc key type
+     * @param keyType
+     * @returns MAC OS key type
+     */
+    const CFTypeRef 
+    getAsymKeyType(KeyType keyType);
+  
+    /**
+     * convert keyClass to MAC OS key class
+     * @param keyClass
+     * @returns MAC OS key class
+     */
+    const CFTypeRef 
+    getKeyClass(KeyClass keyClass);
+  
+    /**
+     * convert digestAlgo to MAC OS algorithm id
+     * @param digestAlgo
+     * @returns MAC OS algorithm id
+     */
+    const CFStringRef 
+    getDigestAlgorithm(DigestAlgorithm digestAlgo);
+  
+    /**
+     * get the digest size of the corresponding algorithm
+     * @param digestAlgo the digest algorithm
+     * @return digest size
+     */
+    long 
+    getDigestSize(DigestAlgorithm digestAlgo);
+
+    ///////////////////////////////////////////////
+    // everything here is public, including data //
+    ///////////////////////////////////////////////
+  public:
+    const std::string keyChainName_;
+    SecKeychainRef keyChainRef_;
+    SecKeychainRef originalDefaultKeyChain_;
+  };
+
+
+
   OSXPrivateKeyStorage::OSXPrivateKeyStorage(const string & keychainName)
-    : keyChainName_("" == keychainName ?  "NDN.keychain" : keychainName)
+    : impl_(new Impl(keychainName))
   {
-    OSStatus res = SecKeychainCreate(keyChainName_.c_str(), //Keychain path
+    OSStatus res = SecKeychainCreate(impl_->keyChainName_.c_str(), //Keychain path
                                       0,                       //Keychain password length
                                       NULL,                    //Keychain password
                                       true,                    //User prompt
                                       NULL,                    //Initial access of Keychain
-                                      &keyChainRef_);         //Keychain reference
+                                      &impl_->keyChainRef_);   //Keychain reference
 
     if (res == errSecDuplicateKeychain)
-      res = SecKeychainOpen(keyChainName_.c_str(),
-                             &keyChainRef_);
+      res = SecKeychainOpen(impl_->keyChainName_.c_str(),
+                            &impl_->keyChainRef_);
 
     if (res != errSecSuccess){
       _LOG_DEBUG("Fail to initialize keychain ref: " << res);
-      throw SecurityException("Fail to initialize keychain ref");
+      throw Error("Fail to initialize keychain ref");
     }
 
-    res = SecKeychainCopyDefault(&originalDefaultKeyChain_);
+    res = SecKeychainCopyDefault(&impl_->originalDefaultKeyChain_);
 
-    res = SecKeychainSetDefault(keyChainRef_);
+    res = SecKeychainSetDefault(impl_->keyChainRef_);
     if (res != errSecSuccess){
       _LOG_DEBUG("Fail to set default keychain: " << res);
-      throw SecurityException("Fail to set default keychain");
+      throw Error("Fail to set default keychain");
     }
   }
 
@@ -61,10 +140,10 @@
     
     if(doesKeyExist(keyName, KEY_CLASS_PUBLIC)){
       _LOG_DEBUG("keyName has existed");
-      throw SecurityException("keyName has existed");
+      throw Error("keyName has existed");
     }
 
-    string keyNameUri = toInternalKeyName(keyName, KEY_CLASS_PUBLIC);
+    string keyNameUri = impl_->toInternalKeyName(keyName, KEY_CLASS_PUBLIC);
 
     SecKeyRef publicKey, privateKey;
 
@@ -77,7 +156,7 @@
                                                              &kCFTypeDictionaryKeyCallBacks,
                                                              NULL);
 
-    CFDictionaryAddValue(attrDict, kSecAttrKeyType, getAsymKeyType(keyType));
+    CFDictionaryAddValue(attrDict, kSecAttrKeyType, impl_->getAsymKeyType(keyType));
     CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(NULL, kCFNumberIntType, &keySize));
     CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
 
@@ -88,7 +167,7 @@
 
     if (res != errSecSuccess){
       _LOG_DEBUG("Fail to create a key pair: " << res);
-      throw SecurityException("Fail to create a key pair");
+      throw Error("Fail to create a key pair");
     }
   }
 
@@ -97,9 +176,9 @@
   {
 
     if(doesKeyExist(keyName, KEY_CLASS_SYMMETRIC))
-        throw SecurityException("keyName has existed!");
+        throw Error("keyName has existed!");
 
-    string keyNameUri =  toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
+    string keyNameUri =  impl_->toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
 
     CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                                 0,
@@ -110,7 +189,7 @@
                                                      keyNameUri.c_str(), 
                                                      kCFStringEncodingUTF8);
 
-    CFDictionaryAddValue(attrDict, kSecAttrKeyType, getSymKeyType(keyType));
+    CFDictionaryAddValue(attrDict, kSecAttrKeyType, impl_->getSymKeyType(keyType));
     CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &keySize));
     CFDictionaryAddValue(attrDict, kSecAttrIsPermanent, kCFBooleanTrue);
     CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
@@ -120,14 +199,15 @@
     SecKeyRef symmetricKey = SecKeyGenerateSymmetric(attrDict, &error);
 
     if (error) 
-        throw SecurityException("Fail to create a symmetric key");
+        throw Error("Fail to create a symmetric key");
   }
 
-  ptr_lib::shared_ptr<PublicKey> OSXPrivateKeyStorage::getPublicKey(const Name & keyName)
+  ptr_lib::shared_ptr<PublicKey>
+  OSXPrivateKeyStorage::getPublicKey(const Name & keyName)
   {
     _LOG_TRACE("OSXPrivateKeyStorage::getPublickey");
 
-    SecKeychainItemRef publicKey = getKey(keyName, KEY_CLASS_PUBLIC);
+    SecKeychainItemRef publicKey = impl_->getKey(keyName, KEY_CLASS_PUBLIC);
 
     CFDataRef exportedKey;
 
@@ -136,59 +216,78 @@
                                   0,
                                   NULL,
                                   &exportedKey);
-    
-    Blob blob(CFDataGetBytePtr(exportedKey), CFDataGetLength(exportedKey));
 
-    return PublicKey::fromDer(blob);
+    return ptr_lib::make_shared<PublicKey>(CFDataGetBytePtr(exportedKey), CFDataGetLength(exportedKey));
   }
 
-  Blob OSXPrivateKeyStorage::sign(const uint8_t *data, size_t dataLength, const Name & keyName, DigestAlgorithm digestAlgo)
+  Block
+  OSXPrivateKeyStorage::sign(const uint8_t *data, size_t dataLength,
+                             const Name& keyName, DigestAlgorithm digestAlgorithm/* = DIGEST_ALGORITHM_SHA256*/)
   {
     _LOG_TRACE("OSXPrivateKeyStorage::Sign");
     
-    CFDataRef dataRef = CFDataCreate(NULL,
-                                      reinterpret_cast<const unsigned char*>(data),
-                                      dataLength
-                                      );
+    CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL,
+                                                    data,
+                                                    dataLength,
+                                                    kCFAllocatorNull
+                                                    );
 
-    SecKeyRef privateKey = (SecKeyRef)getKey(keyName, KEY_CLASS_PRIVATE);
+    SecKeyRef privateKey = (SecKeyRef)impl_->getKey(keyName, KEY_CLASS_PRIVATE);
     
     CFErrorRef error;
     SecTransformRef signer = SecSignTransformCreate((SecKeyRef)privateKey, &error);
-    if (error) throw SecurityException("Fail to create signer");
-    
+    if (error) throw Error("Fail to create signer");
+
+    // Set input
     Boolean set_res = SecTransformSetAttribute(signer,
                                                kSecTransformInputAttributeName,
                                                dataRef,
                                                &error);
-    if (error) throw SecurityException("Fail to configure input of signer");
+    if (error) throw Error("Fail to configure input of signer");
 
+    // Enable use of padding
+    SecTransformSetAttribute(
+                             signer,
+                             kSecPaddingKey,
+                             kSecPaddingPKCS1Key,
+                             &error);
+    if (error) throw Error("Fail to configure digest algorithm of signer");
+
+    // Set padding type
     set_res = SecTransformSetAttribute(signer,
                                        kSecDigestTypeAttribute,
-                                       getDigestAlgorithm(digestAlgo),
+                                       impl_->getDigestAlgorithm(digestAlgorithm),
                                        &error);
-    if (error) throw SecurityException("Fail to configure digest algorithm of signer");
+    if (error) throw Error("Fail to configure digest algorithm of signer");
 
-    long digestSize = getDigestSize(digestAlgo);
-
+    // Set padding attribute
+    long digestSize = impl_->getDigestSize(digestAlgorithm);
     set_res = SecTransformSetAttribute(signer,
                                        kSecDigestLengthAttribute,
                                        CFNumberCreate(NULL, kCFNumberLongType, &digestSize),
                                        &error);
-    if (error) throw SecurityException("Fail to configure digest size of signer");
+    if (error) throw Error("Fail to configure digest size of signer");
 
+    // Actually sign
     CFDataRef signature = (CFDataRef) SecTransformExecute(signer, &error);
     if (error) {
       CFShow(error);
-      throw SecurityException("Fail to sign data");
+      throw Error("Fail to sign data");
     }
 
-    if (!signature) throw SecurityException("Signature is NULL!\n");
+    if (!signature) throw Error("Signature is NULL!\n");
 
-    return Blob(CFDataGetBytePtr(signature), CFDataGetLength(signature));
+    return Block(Tlv::SignatureValue, ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(signature), CFDataGetLength(signature)));
   }
 
-  Blob OSXPrivateKeyStorage::decrypt(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
+  void
+  OSXPrivateKeyStorage::sign(Data &data,
+                             const Name& keyName, DigestAlgorithm digestAlgorithm/* = DIGEST_ALGORITHM_SHA256 */)
+  {
+  }
+
+  ConstBufferPtr
+  OSXPrivateKeyStorage::decrypt(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
   {
     _LOG_TRACE("OSXPrivateKeyStorage::Decrypt");
 
@@ -205,34 +304,35 @@
 
     // _LOG_DEBUG("CreateData");
     
-    SecKeyRef decryptKey = (SecKeyRef)getKey(keyName, keyClass);
+    SecKeyRef decryptKey = (SecKeyRef)impl_->getKey(keyName, keyClass);
 
     // _LOG_DEBUG("GetKey");
 
     CFErrorRef error;
     SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
-    if (error) throw SecurityException("Fail to create decrypt");
+    if (error) throw Error("Fail to create decrypt");
 
     Boolean set_res = SecTransformSetAttribute(decrypt,
                                                kSecTransformInputAttributeName,
                                                dataRef,
                                                &error);
-    if (error) throw SecurityException("Fail to configure decrypt");
+    if (error) throw Error("Fail to configure decrypt");
 
     CFDataRef output = (CFDataRef) SecTransformExecute(decrypt, &error);
     if (error)
       {
         CFShow(error);
-        throw SecurityException("Fail to decrypt data");
+        throw Error("Fail to decrypt data");
       }
-    if (!output) throw SecurityException("Output is NULL!\n");
+    if (!output) throw Error("Output is NULL!\n");
 
-    return Blob(CFDataGetBytePtr(output), CFDataGetLength(output));
+    return ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(output), CFDataGetLength(output));
   }
   
-  bool OSXPrivateKeyStorage::setACL(const Name & keyName, KeyClass keyClass, int acl, const string & appPath)
+  bool
+  OSXPrivateKeyStorage::setACL(const Name & keyName, KeyClass keyClass, int acl, const string & appPath)
   {
-    SecKeychainItemRef privateKey = getKey(keyName, keyClass);
+    SecKeychainItemRef privateKey = impl_->getKey(keyName, keyClass);
     
     SecAccessRef accRef;
     OSStatus acc_res = SecKeychainItemCopyAccess(privateKey, &accRef);
@@ -279,53 +379,55 @@
     return true;
   }
 
-  bool OSXPrivateKeyStorage::verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo)
-  {
-    _LOG_TRACE("OSXPrivateKeyStorage::Verify");
+  // bool
+  // OSXPrivateKeyStorage::verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo)
+  // {
+  //   _LOG_TRACE("OSXPrivateKeyStorage::Verify");
     
-    CFDataRef dataRef = CFDataCreate(NULL,
-                                      reinterpret_cast<const unsigned char*>(pData.buf()),
-                                      pData.size());
+  //   CFDataRef dataRef = CFDataCreate(NULL,
+  //                                     reinterpret_cast<const unsigned char*>(pData.buf()),
+  //                                     pData.size());
 
-    CFDataRef sigRef = CFDataCreate(NULL,
-                                     reinterpret_cast<const unsigned char*>(pSig.buf()),
-                                     pSig.size());
+  //   CFDataRef sigRef = CFDataCreate(NULL,
+  //                                    reinterpret_cast<const unsigned char*>(pSig.buf()),
+  //                                    pSig.size());
 
-    SecKeyRef publicKey = (SecKeyRef)getKey(keyName, KEY_CLASS_PUBLIC);
+  //   SecKeyRef publicKey = (SecKeyRef)impl_->getKey(keyName, KEY_CLASS_PUBLIC);
     
-    CFErrorRef error;
-    SecTransformRef verifier = SecVerifyTransformCreate(publicKey, sigRef, &error);
-    if (error) throw SecurityException("Fail to create verifier");
+  //   CFErrorRef error;
+  //   SecTransformRef verifier = SecVerifyTransformCreate(publicKey, sigRef, &error);
+  //   if (error) throw Error("Fail to create verifier");
     
-    Boolean set_res = SecTransformSetAttribute(verifier,
-                                               kSecTransformInputAttributeName,
-                                               dataRef,
-                                               &error);
-    if (error) throw SecurityException("Fail to configure input of verifier");
+  //   Boolean set_res = SecTransformSetAttribute(verifier,
+  //                                              kSecTransformInputAttributeName,
+  //                                              dataRef,
+  //                                              &error);
+  //   if (error) throw Error("Fail to configure input of verifier");
 
-    set_res = SecTransformSetAttribute(verifier,
-                                       kSecDigestTypeAttribute,
-                                       getDigestAlgorithm(digestAlgo),
-                                       &error);
-    if (error) throw SecurityException("Fail to configure digest algorithm of verifier");
+  //   set_res = SecTransformSetAttribute(verifier,
+  //                                      kSecDigestTypeAttribute,
+  //                                      impl_->getDigestAlgorithm(digestAlgo),
+  //                                      &error);
+  //   if (error) throw Error("Fail to configure digest algorithm of verifier");
 
-    long digestSize = getDigestSize(digestAlgo);
-    set_res = SecTransformSetAttribute(verifier,
-                                       kSecDigestLengthAttribute,
-                                       CFNumberCreate(NULL, kCFNumberLongType, &digestSize),
-                                       &error);
-    if (error) throw SecurityException("Fail to configure digest size of verifier");
+  //   long digestSize = impl_->getDigestSize(digestAlgo);
+  //   set_res = SecTransformSetAttribute(verifier,
+  //                                      kSecDigestLengthAttribute,
+  //                                      CFNumberCreate(NULL, kCFNumberLongType, &digestSize),
+  //                                      &error);
+  //   if (error) throw Error("Fail to configure digest size of verifier");
 
-    CFBooleanRef result = (CFBooleanRef) SecTransformExecute(verifier, &error);
-    if (error) throw SecurityException("Fail to verify data");
+  //   CFBooleanRef result = (CFBooleanRef) SecTransformExecute(verifier, &error);
+  //   if (error) throw Error("Fail to verify data");
 
-    if (result == kCFBooleanTrue)
-      return true;
-    else
-      return false;
-  }
+  //   if (result == kCFBooleanTrue)
+  //     return true;
+  //   else
+  //     return false;
+  // }
 
-  Blob OSXPrivateKeyStorage::encrypt(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
+  ConstBufferPtr
+  OSXPrivateKeyStorage::encrypt(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
   {
     _LOG_TRACE("OSXPrivateKeyStorage::Encrypt");
 
@@ -340,31 +442,32 @@
                                       dataLength
                                       );
     
-    SecKeyRef encryptKey = (SecKeyRef)getKey(keyName, keyClass);
+    SecKeyRef encryptKey = (SecKeyRef)impl_->getKey(keyName, keyClass);
 
     CFErrorRef error;
     SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
-    if (error) throw SecurityException("Fail to create encrypt");
+    if (error) throw Error("Fail to create encrypt");
 
     Boolean set_res = SecTransformSetAttribute(encrypt,
                                                kSecTransformInputAttributeName,
                                                dataRef,
                                                &error);
-    if (error) throw SecurityException("Fail to configure encrypt");
+    if (error) throw Error("Fail to configure encrypt");
 
     CFDataRef output = (CFDataRef) SecTransformExecute(encrypt, &error);
-    if (error) throw SecurityException("Fail to encrypt data");
+    if (error) throw Error("Fail to encrypt data");
 
-    if (!output) throw SecurityException("Output is NULL!\n");
+    if (!output) throw Error("Output is NULL!\n");
 
-    return Blob(CFDataGetBytePtr(output), CFDataGetLength(output));
+    return ptr_lib::make_shared<Buffer> (CFDataGetBytePtr(output), CFDataGetLength(output));
   }
 
-  bool OSXPrivateKeyStorage::doesKeyExist(const Name & keyName, KeyClass keyClass)
+  bool
+  OSXPrivateKeyStorage::doesKeyExist(const Name & keyName, KeyClass keyClass)
   {
     _LOG_TRACE("OSXPrivateKeyStorage::doesKeyExist");
 
-    string keyNameUri = toInternalKeyName(keyName, keyClass);
+    string keyNameUri = impl_->toInternalKeyName(keyName, keyClass);
 
     CFStringRef keyLabel = CFStringCreateWithCString(NULL, 
                                                      keyNameUri.c_str(), 
@@ -375,7 +478,7 @@
                                                                 &kCFTypeDictionaryKeyCallBacks,
                                                                 NULL);
 
-    CFDictionaryAddValue(attrDict, kSecAttrKeyClass, getKeyClass(keyClass));
+    CFDictionaryAddValue(attrDict, kSecAttrKeyClass, impl_->getKeyClass(keyClass));
     CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
     CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
     
@@ -389,7 +492,13 @@
 
   }
 
-  SecKeychainItemRef OSXPrivateKeyStorage::getKey(const Name & keyName, KeyClass keyClass)
+
+  ////////////////////////////////
+  // OSXPrivateKeyStorage::Impl //
+  ////////////////////////////////
+
+  SecKeychainItemRef
+  OSXPrivateKeyStorage::Impl::getKey(const Name & keyName, KeyClass keyClass)
   {
     string keyNameUri = toInternalKeyName(keyName, keyClass);
 
@@ -419,7 +528,7 @@
       return keyItem;
   }
   
-  string OSXPrivateKeyStorage::toInternalKeyName(const Name & keyName, KeyClass keyClass)
+  string OSXPrivateKeyStorage::Impl::toInternalKeyName(const Name & keyName, KeyClass keyClass)
   {
     string keyUri = keyName.toUri();
 
@@ -429,7 +538,7 @@
       return keyUri;
   }
 
-  const CFTypeRef OSXPrivateKeyStorage::getAsymKeyType(KeyType keyType)
+  const CFTypeRef OSXPrivateKeyStorage::Impl::getAsymKeyType(KeyType keyType)
   {
     switch(keyType){
     case KEY_TYPE_RSA:
@@ -440,7 +549,7 @@
     }
   }
 
-  const CFTypeRef OSXPrivateKeyStorage::getSymKeyType(KeyType keyType)
+  const CFTypeRef OSXPrivateKeyStorage::Impl::getSymKeyType(KeyType keyType)
   {
     switch(keyType){
     case KEY_TYPE_AES:
@@ -451,7 +560,7 @@
     }
   }
 
-  const CFTypeRef OSXPrivateKeyStorage::getKeyClass(KeyClass keyClass)
+  const CFTypeRef OSXPrivateKeyStorage::Impl::getKeyClass(KeyClass keyClass)
   {
     switch(keyClass){
     case KEY_CLASS_PRIVATE:
@@ -466,7 +575,7 @@
     }
   }
 
-  const CFStringRef OSXPrivateKeyStorage::getDigestAlgorithm(DigestAlgorithm digestAlgo)
+  const CFStringRef OSXPrivateKeyStorage::Impl::getDigestAlgorithm(DigestAlgorithm digestAlgo)
   {
     switch(digestAlgo){
     // case DIGEST_MD2:
@@ -483,7 +592,7 @@
     }
   }
 
-  long OSXPrivateKeyStorage::getDigestSize(DigestAlgorithm digestAlgo)
+  long OSXPrivateKeyStorage::Impl::getDigestSize(DigestAlgorithm digestAlgo)
   {
     switch(digestAlgo){
     case DIGEST_ALGORITHM_SHA256: