cert_test_util_nss.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/test/cert_test_util.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <pk11pub.h> 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <secmodt.h> 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_path.h" 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_util.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/path_service.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "crypto/nss_util.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "crypto/rsa_private_key.h" 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "net/cert/cert_type.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace net { 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile( 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::FilePath& dir, 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& key_filename, 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PK11SlotInfo* slot) { 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FilePath key_path = dir.AppendASCII(key_filename); 24 std::string key_pkcs8; 25 bool success = base::ReadFileToString(key_path, &key_pkcs8); 26 if (!success) { 27 LOG(ERROR) << "Failed to read file " << key_path.value(); 28 return scoped_ptr<crypto::RSAPrivateKey>(); 29 } 30 31 const uint8* key_pkcs8_begin = 32 reinterpret_cast<const uint8*>(key_pkcs8.data()); 33 std::vector<uint8> key_vector(key_pkcs8_begin, 34 key_pkcs8_begin + key_pkcs8.length()); 35 36 scoped_ptr<crypto::RSAPrivateKey> private_key( 37 crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, 38 key_vector)); 39 LOG_IF(ERROR, !private_key) << "Could not create key from file " 40 << key_path.value(); 41 return private_key.Pass(); 42} 43 44bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert, 45 PK11SlotInfo* slot) { 46 std::string nickname = cert->GetDefaultNickname(USER_CERT); 47 { 48 crypto::AutoNSSWriteLock lock; 49 SECStatus rv = PK11_ImportCert(slot, 50 cert->os_cert_handle(), 51 CK_INVALID_HANDLE, 52 nickname.c_str(), 53 PR_FALSE); 54 if (rv != SECSuccess) { 55 LOG(ERROR) << "Could not import cert"; 56 return false; 57 } 58 } 59 return true; 60} 61 62scoped_refptr<X509Certificate> ImportClientCertAndKeyFromFile( 63 const base::FilePath& dir, 64 const std::string& cert_filename, 65 const std::string& key_filename, 66 PK11SlotInfo* slot) { 67 if (!ImportSensitiveKeyFromFile(dir, key_filename, slot)) { 68 LOG(ERROR) << "Could not import private key from file " << key_filename; 69 return NULL; 70 } 71 72 scoped_refptr<X509Certificate> cert(ImportCertFromFile(dir, cert_filename)); 73 74 if (!cert.get()) { 75 LOG(ERROR) << "Failed to parse cert from file " << cert_filename; 76 return NULL; 77 } 78 79 if (!ImportClientCertToSlot(cert, slot)) 80 return NULL; 81 82 // |cert| continues to point to the original X509Certificate before the 83 // import to |slot|. However this should not make a difference as NSS handles 84 // state globally. 85 return cert; 86} 87 88} // namespace net 89