15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/sym_key_nss.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/crypto_data.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/key_nss.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/util_nss.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/status.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/webcrypto_util.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "crypto/scoped_nss_types.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content {
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace webcrypto {
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            bool extractable,
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            blink::WebCryptoKeyUsageMask usage_mask,
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            unsigned keylen_bytes,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            CK_MECHANISM_TYPE mechanism,
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            blink::WebCryptoKey* key) {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_NE(CKM_INVALID_MECHANISM, mechanism);
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!slot)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Status::OperationError();
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11SymKey pk11_key(
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PK11_KeyGen(slot.get(), mechanism, NULL, keylen_bytes, NULL));
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!pk11_key)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Status::OperationError();
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (PK11_ExtractKeyValue(pk11_key.get()) != SECSuccess)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Status::OperationError();
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const SECItem* key_data = PK11_GetKeyData(pk11_key.get());
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!key_data)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Status::OperationError();
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<SymKeyNss> handle(new SymKeyNss(
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      pk11_key.Pass(), CryptoData(key_data->data, key_data->len)));
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  *key = blink::WebCryptoKey::create(handle.release(),
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     blink::WebCryptoKeyTypeSecret,
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     extractable,
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     algorithm,
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     usage_mask);
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return Status::Success();
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)Status ImportKeyRawNss(const CryptoData& key_data,
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const blink::WebCryptoKeyAlgorithm& algorithm,
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       bool extractable,
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       blink::WebCryptoKeyUsageMask usage_mask,
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       CK_MECHANISM_TYPE mechanism,
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       CK_FLAGS flags,
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       blink::WebCryptoKey* key) {
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!algorithm.isNull());
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SECItem key_item = MakeSECItemForBuffer(key_data);
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11SymKey pk11_sym_key(
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PK11_ImportSymKeyWithFlags(slot.get(),
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 mechanism,
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 PK11_OriginUnwrap,
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 CKA_FLAGS_ONLY,
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 &key_item,
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 flags,
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 false,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 NULL));
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!pk11_sym_key.get())
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Status::OperationError();
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<SymKeyNss> handle(new SymKeyNss(pk11_sym_key.Pass(), key_data));
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  *key = blink::WebCryptoKey::create(handle.release(),
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     blink::WebCryptoKeyTypeSecret,
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     extractable,
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     algorithm,
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     usage_mask);
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return Status::Success();
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace webcrypto
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace content
92