Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: net/base/cert_database_nss.cc

Issue 652137: Mac: implement <keygen> support, including adding generated cert to the Keychain. (Closed)
Patch Set: Responding to review feedback. Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/cert_database.h" 5 #include "net/base/cert_database.h"
6 6
7 #include <pk11pub.h> 7 #include <pk11pub.h>
8 #include <secmod.h> 8 #include <secmod.h>
9 #include <ssl.h> 9 #include <ssl.h>
10 #include <nssb64.h> // NSSBase64_EncodeItem() 10 #include <nssb64.h> // NSSBase64_EncodeItem()
11 #include <secder.h> // DER_Encode() 11 #include <secder.h> // DER_Encode()
12 #include <cryptohi.h> // SEC_DerSignData() 12 #include <cryptohi.h> // SEC_DerSignData()
13 #include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo() 13 #include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo()
14 14
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/scoped_ptr.h" 16 #include "base/scoped_ptr.h"
17 #include "base/nss_util.h" 17 #include "base/nss_util.h"
18 #include "net/base/net_errors.h"
18 19
19 namespace net { 20 namespace net {
20 21
21 CertDatabase::CertDatabase() { 22 CertDatabase::CertDatabase() {
22 Init(); 23 Init();
23 } 24 }
24 25
25 bool CertDatabase::AddUserCert(const char* data, int len) { 26 int CertDatabase::CheckUserCert(X509Certificate* cert_obj) {
26 CERTCertificate* cert = NULL; 27 if (!cert_obj)
27 PK11SlotInfo* slot = NULL; 28 return ERR_CERT_INVALID;
28 std::string nickname; 29 if (cert_obj->HasExpired())
29 bool is_success = true; 30 return ERR_CERT_DATE_INVALID;
30
31 // Make a copy of "data" since CERT_DecodeCertPackage
32 // might modify it.
33 char* data_copy = new char[len];
34 memcpy(data_copy, data, len);
35
36 // Parse into a certificate structure.
37 cert = CERT_DecodeCertFromPackage(data_copy, len);
38 delete [] data_copy;
39 if (!cert) {
40 LOG(ERROR) << "Couldn't create a temporary certificate";
41 return false;
42 }
43 31
44 // Check if the private key corresponding to the certificate exist 32 // Check if the private key corresponding to the certificate exist
45 // We shouldn't accept any random client certificate sent by a CA. 33 // We shouldn't accept any random client certificate sent by a CA.
46 34
47 // Note: The NSS source documentation wrongly suggests that this 35 // Note: The NSS source documentation wrongly suggests that this
48 // also imports the certificate if the private key exists. This 36 // also imports the certificate if the private key exists. This
49 // doesn't seem to be the case. 37 // doesn't seem to be the case.
50 38
51 slot = PK11_KeyForCertExists(cert, NULL, NULL); 39 CERTCertificate* cert = cert_obj->os_cert_handle();
40 PK11SlotInfo* slot = PK11_KeyForCertExists(cert, NULL, NULL);
52 if (!slot) { 41 if (!slot) {
53 LOG(ERROR) << "No corresponding private key in store"; 42 LOG(ERROR) << "No corresponding private key in store";
54 CERT_DestroyCertificate(cert); 43 return ERR_CERT_NO_PRIVATE_KEY;
55 return false;
56 } 44 }
57 PK11_FreeSlot(slot); 45 PK11_FreeSlot(slot);
58 slot = NULL;
59 46
60 // TODO(gauravsh): We also need to make sure another certificate 47 return OK;
61 // doesn't already exist for the same private key. 48 }
49
50 int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
51 CERTCertificate* cert = cert_obj->os_cert_handle();
52 PK11SlotInfo* slot = NULL;
53 std::string nickname;
54 bool is_success = true;
62 55
63 // Create a nickname for this certificate. 56 // Create a nickname for this certificate.
64 // We use the scheme used by Firefox: 57 // We use the scheme used by Firefox:
65 // --> <subject's common name>'s <issuer's common name> ID. 58 // --> <subject's common name>'s <issuer's common name> ID.
66 //
67 59
68 std::string username, ca_name; 60 std::string username, ca_name;
69 char* temp_username = CERT_GetCommonName(&cert->subject); 61 char* temp_username = CERT_GetCommonName(&cert->subject);
70 char* temp_ca_name = CERT_GetCommonName(&cert->issuer); 62 char* temp_ca_name = CERT_GetCommonName(&cert->issuer);
71 if (temp_username) { 63 if (temp_username) {
72 username = temp_username; 64 username = temp_username;
73 PORT_Free(temp_username); 65 PORT_Free(temp_username);
74 } 66 }
75 if (temp_ca_name) { 67 if (temp_ca_name) {
76 ca_name = temp_ca_name; 68 ca_name = temp_ca_name;
77 PORT_Free(temp_ca_name); 69 PORT_Free(temp_ca_name);
78 } 70 }
79 nickname = username + "'s " + ca_name + " ID"; 71 nickname = username + "'s " + ca_name + " ID";
80 72
81 slot = PK11_ImportCertForKey(cert, 73 slot = PK11_ImportCertForKey(cert,
82 const_cast<char*>(nickname.c_str()), 74 const_cast<char*>(nickname.c_str()),
83 NULL); 75 NULL);
84 if (slot) { 76 if (slot) {
85 PK11_FreeSlot(slot); 77 PK11_FreeSlot(slot);
86 } else { 78 } else {
87 LOG(ERROR) << "Couldn't import user certificate."; 79 LOG(ERROR) << "Couldn't import user certificate.";
88 is_success = false; 80 is_success = false;
89 } 81 }
90 CERT_DestroyCertificate(cert);
91 return is_success; 82 return is_success;
92 } 83 }
93 84
94 void CertDatabase::Init() { 85 void CertDatabase::Init() {
95 base::EnsureNSSInit(); 86 base::EnsureNSSInit();
96 } 87 }
97 88
98 } // namespace net 89 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698