1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/test/cert_test_util.h" 6 7#include <pk11pub.h> 8#include <secmodt.h> 9 10#include "base/files/file_path.h" 11#include "base/files/file_util.h" 12#include "base/path_service.h" 13#include "crypto/nss_util.h" 14#include "crypto/rsa_private_key.h" 15#include "net/cert/cert_type.h" 16 17namespace net { 18 19scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile( 20 const base::FilePath& dir, 21 const std::string& key_filename, 22 PK11SlotInfo* slot) { 23 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