1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/test/cert_test_util.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <pk11pub.h> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <secmodt.h> 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/files/file_path.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/path_service.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "crypto/nss_util.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crypto/rsa_private_key.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/cert/cert_type.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net { 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile( 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& dir, 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& key_filename, 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PK11SlotInfo* slot) { 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::FilePath key_path = dir.AppendASCII(key_filename); 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string key_pkcs8; 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool success = base::ReadFileToString(key_path, &key_pkcs8); 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!success) { 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Failed to read file " << key_path.value(); 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return scoped_ptr<crypto::RSAPrivateKey>(); 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const uint8* key_pkcs8_begin = 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reinterpret_cast<const uint8*>(key_pkcs8.data()); 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<uint8> key_vector(key_pkcs8_begin, 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key_pkcs8_begin + key_pkcs8.length()); 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<crypto::RSAPrivateKey> private_key( 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key_vector)); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_IF(ERROR, !private_key) << "Could not create key from file " 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << key_path.value(); 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return private_key.Pass(); 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert, 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PK11SlotInfo* slot) { 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string nickname = cert->GetDefaultNickname(USER_CERT); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::AutoNSSWriteLock lock; 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECStatus rv = PK11_ImportCert(slot, 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cert->os_cert_handle(), 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CK_INVALID_HANDLE, 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nickname.c_str(), 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PR_FALSE); 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (rv != SECSuccess) { 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Could not import cert"; 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_refptr<X509Certificate> ImportClientCertAndKeyFromFile( 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& dir, 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& cert_filename, 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& key_filename, 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PK11SlotInfo* slot) { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ImportSensitiveKeyFromFile(dir, key_filename, slot)) { 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Could not import private key from file " << key_filename; 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<X509Certificate> cert(ImportCertFromFile(dir, cert_filename)); 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!cert.get()) { 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Failed to parse cert from file " << cert_filename; 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ImportClientCertToSlot(cert, slot)) 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |cert| continues to point to the original X509Certificate before the 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // import to |slot|. However this should not make a difference as NSS handles 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // state globally. 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return cert; 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace net 89