summaryrefslogtreecommitdiffstats
path: root/base/crypto/symmetric_key_nss.cc
diff options
context:
space:
mode:
Diffstat (limited to 'base/crypto/symmetric_key_nss.cc')
-rw-r--r--base/crypto/symmetric_key_nss.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/base/crypto/symmetric_key_nss.cc b/base/crypto/symmetric_key_nss.cc
index ed4804f..1405677 100644
--- a/base/crypto/symmetric_key_nss.cc
+++ b/base/crypto/symmetric_key_nss.cc
@@ -12,6 +12,10 @@
namespace base {
+SymmetricKey::SymmetricKey(PK11SymKey* key) : key_(key) {
+ DCHECK(key);
+}
+
SymmetricKey::~SymmetricKey() {}
// static
@@ -80,6 +84,33 @@ SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
return new SymmetricKey(sym_key);
}
+// static
+SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
+ const std::string& raw_key) {
+ CK_MECHANISM_TYPE cipher =
+ algorithm == AES ? CKM_AES_KEY_GEN : CKM_SHA_1_HMAC;
+
+ SECItem key_item;
+ key_item.type = siBuffer;
+ key_item.data = reinterpret_cast<unsigned char*>(
+ const_cast<char *>(raw_key.data()));
+ key_item.len = raw_key.size();
+
+ ScopedPK11Slot slot(PK11_GetBestSlot(cipher, NULL));
+ if (!slot.get())
+ return NULL;
+
+ // The exact value of the |origin| argument doesn't matter to NSS as long as
+ // it's not PK11_OriginFortezzaHack, so we pass PK11_OriginUnwrap as a
+ // placeholder.
+ PK11SymKey* sym_key = PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, NULL);
+ if (!sym_key)
+ return NULL;
+
+ return new SymmetricKey(sym_key);
+}
+
bool SymmetricKey::GetRawKey(std::string* raw_key) {
SECStatus rv = PK11_ExtractKeyValue(key_.get());
if (SECSuccess != rv)