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

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

Issue 261035: Adds support for the <keygen> tag for client certificate enrollment under Lin... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 2 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 | Annotate | Revision Log
Property Changes:
Name: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/base/cert_database.h"
6
7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
8 // until NSS 3.12.2 comes out and we update to it.
9 #define Lock FOO_NSS_Lock
10 #include <pk11pub.h>
11 #include <secmod.h>
12 #include <ssl.h>
13 #include <nssb64.h> // NSSBase64_EncodeItem()
14 #include <secder.h> // DER_Encode()
15 #include <cryptohi.h> // SEC_DerSignData()
16 #include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo()
17 #undef Lock
18
19 #include "base/logging.h"
20 #include "base/scoped_ptr.h"
21 #include "base/nss_init.h"
22
23 namespace net {
24
25 CertDatabase::CertDatabase() {
26 Init();
27 }
28
29 bool CertDatabase::AddUserCert(const char* data, int len) {
30 CERTCertificate* cert = NULL;
31 PK11SlotInfo* slot = NULL;
32 std::string nickname;
33 char* data_copy = new char[len];
34 bool is_success = true;
35
36 // Make a copy of "data" since CERT_DecodeCertPackage
37 // might modify it.
38 memcpy(data_copy, data, len);
39
40 // Parse into a certificate structure.
41 cert = CERT_DecodeCertFromPackage(data_copy, len);
42 if (!cert) {
43 LOG(ERROR) << "Couldn't create a temporary certificate";
44 return false;
45 }
46 delete [] data_copy;
47
48 // Check if the private key corresponding to the certificate exist
49 // We shouldn't accept any random client certificate sent by a CA.
50
51 // Note: The NSS source documentation wrongly suggests that this
52 // also imports the certificate if the private key exists. This
53 // doesn't seem to be the case.
54
55 slot = PK11_KeyForCertExists(cert, NULL, NULL);
56 if (!slot) {
57 LOG(ERROR) << "No corresponding private key in store";
58 CERT_DestroyCertificate(cert);
59 return false;
60 }
61 PK11_FreeSlot(slot);
62 slot = NULL;
63
64 // TODO(gauravsh): We also need to make sure another certificate
65 // doesn't already exist for the same private key.
66
67 // Create a nickname for this certificate.
68 // We use the scheme used by Firefox:
69 // --> <subject's common name>'s <issuer's common name> ID.
70 //
71
72 std::string username, ca_name;
73 char* temp_username = CERT_GetCommonName(&cert->subject);
74 char* temp_ca_name = CERT_GetCommonName(&cert->issuer);
75 if (temp_username) {
76 username = temp_username;
77 PORT_Free(temp_username);
78 }
79 if (temp_ca_name) {
80 ca_name = temp_ca_name;
81 PORT_Free(temp_ca_name);
82 }
83 nickname = username + "'s " + ca_name + " ID";
84
85 slot = PK11_ImportCertForKey(cert,
86 const_cast<char*>(nickname.c_str()),
87 NULL);
88 if (slot) {
89 PK11_FreeSlot(slot);
90 } else {
91 LOG(ERROR) << "Couldn't import user certificate.";
92 is_success = false;
93 }
94 CERT_DestroyCertificate(cert);
95 return is_success;
96 }
97
98 void CertDatabase::Init() {
99 base::EnsureNSSInit();
100 }
101
102 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698