diff options
Diffstat (limited to 'base/crypto/symmetric_key_nss.cc')
-rw-r--r-- | base/crypto/symmetric_key_nss.cc | 31 |
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) |