OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "crypto/nss_util.h" | 5 #include "crypto/nss_util.h" |
6 #include "crypto/nss_util_internal.h" | 6 #include "crypto/nss_util_internal.h" |
7 | 7 |
8 #include <nss.h> | 8 #include <nss.h> |
9 #include <plarena.h> | 9 #include <plarena.h> |
10 #include <prerror.h> | 10 #include <prerror.h> |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 return dir; | 76 return dir; |
77 } | 77 } |
78 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); | 78 dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); |
79 if (!file_util::CreateDirectory(dir)) { | 79 if (!file_util::CreateDirectory(dir)) { |
80 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; | 80 LOG(ERROR) << "Failed to create " << dir.value() << " directory."; |
81 dir.clear(); | 81 dir.clear(); |
82 } | 82 } |
83 return dir; | 83 return dir; |
84 } | 84 } |
85 | 85 |
86 #if defined(OS_CHROMEOS) | |
87 | |
88 static unsigned char kSupplementalUserKeyId[] = { | |
wtc
2011/09/02 22:31:08
Nit: remove 'static' because this is in the anonym
zel
2011/09/03 01:52:22
On ChromeOS, this key will be used to perform AES
| |
89 0xCC, 0x13, 0x19, 0xDE, 0x75, 0x5E, 0xFE, 0x00, | |
90 0x5E, 0x71, 0xD4, 0xA6, 0x00, 0x00, 0x00, 0xCC | |
91 }; | |
92 | |
93 const char kSupplementalKeyNickname[] = "ChromeOS_SupplementalUserKey"; | |
94 | |
95 struct SDRResult | |
96 { | |
wtc
2011/09/02 22:31:08
Nit: put '{' on the previous line.
Document what
zel
2011/09/03 01:52:22
I have removed this code addressed in this and com
| |
97 SECItem keyid; | |
98 SECAlgorithmID alg; | |
99 SECItem data; | |
100 }; | |
101 typedef struct SDRResult SDRResult; | |
wtc
2011/09/02 22:31:08
Remove this typedef. This is not necessary in C++
zel
2011/09/03 01:52:22
Removed.
| |
102 | |
103 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | |
104 | |
105 static SEC_ASN1Template g_encoding_template[] = { | |
106 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (SDRResult) }, | |
107 { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, keyid) }, | |
108 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(SDRResult, alg), | |
109 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | |
110 { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, data) }, | |
111 { 0 } | |
112 }; | |
113 | |
114 // Local utility functions for padding/unpadding an incoming data block | |
115 // to the mechanism block size. | |
116 | |
117 SECStatus PadBlock(SECItem *data, unsigned int blockSize, SECItem *result) { | |
wtc
2011/09/02 22:31:08
The function arguments and variables in these func
zel
2011/09/03 01:52:22
Removed.
| |
118 SECStatus rv = SECSuccess; | |
119 unsigned int padLength; | |
120 unsigned int i; | |
121 | |
122 result->data = 0; | |
123 result->len = 0; | |
124 | |
125 // This algorithm always adds to the block (to indicate the number | |
126 // of pad bytes). So allocate a block large enough. | |
127 padLength = blockSize - (data->len % blockSize); | |
128 result->len = data->len + padLength; | |
129 result->data = (unsigned char *) PORT_Alloc(result->len); | |
wtc
2011/09/02 22:31:08
Nit: try to use C++ casts where possible.
This is
zel
2011/09/03 01:52:22
Removed.
| |
130 | |
131 // Copy the data | |
132 PORT_Memcpy(result->data, data->data, data->len); | |
133 | |
134 // Add the pad values | |
135 for(i = data->len; i < result->len; i++) | |
136 result->data[i] = (unsigned char) padLength; | |
137 | |
138 return rv; | |
139 } | |
140 | |
141 SECStatus UnpadBlock(SECItem *data, unsigned int blockSize, SECItem *result) { | |
142 SECStatus rv = SECSuccess; | |
143 unsigned int padLength; | |
144 unsigned int i; | |
145 | |
146 result->data = 0; | |
147 result->len = 0; | |
148 | |
149 // Remove the padding from the end if the input data. | |
150 if (data->len == 0 || data->len % blockSize != 0) { | |
151 rv = SECFailure; | |
152 goto done; | |
153 } | |
154 | |
155 padLength = data->data[data->len-1]; | |
156 if (padLength > blockSize) { | |
157 rv = SECFailure; | |
158 goto done; | |
159 } | |
160 | |
161 // Verify padding. | |
162 for (i = data->len - padLength; i < data->len; i++) { | |
163 if (data->data[i] != padLength) { | |
164 rv = SECFailure; | |
165 goto done; | |
166 } | |
167 } | |
168 | |
169 result->len = data->len - padLength; | |
170 result->data = (unsigned char *) PORT_Alloc(result->len); | |
171 if (!result->data) { | |
172 rv = SECFailure; | |
173 goto done; | |
174 } | |
175 | |
176 PORT_Memcpy(result->data, data->data, result->len); | |
177 | |
178 if (padLength < 2) { | |
179 return SECWouldBlock; | |
180 } | |
181 | |
182 done: | |
183 return rv; | |
184 } | |
185 | |
186 // decrypt a block | |
187 SECStatus pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena, | |
188 CK_MECHANISM_TYPE type, PK11SymKey *key, | |
189 SECItem *params, SECItem *in, SECItem *result) { | |
190 PK11Context *ctx = 0; | |
191 SECItem paddedResult; | |
192 SECStatus rv; | |
193 | |
194 paddedResult.len = 0; | |
195 paddedResult.data = 0; | |
196 | |
197 ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params); | |
198 if (!ctx) { | |
199 rv = SECFailure; | |
200 goto done; | |
201 } | |
202 | |
203 paddedResult.len = in->len; | |
204 paddedResult.data = reinterpret_cast<unsigned char *>( | |
205 PORT_ArenaAlloc(arena, paddedResult.len)); | |
206 | |
207 rv = PK11_CipherOp(ctx, paddedResult.data, | |
208 reinterpret_cast<int*>(&paddedResult.len), paddedResult.len, | |
209 in->data, in->len); | |
210 if (rv != SECSuccess) | |
211 goto done; | |
212 | |
213 PK11_Finalize(ctx); | |
214 | |
215 // Remove the padding. | |
216 rv = UnpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result); | |
217 if (rv) | |
218 goto done; | |
219 | |
220 done: | |
221 if (ctx) | |
222 PK11_DestroyContext(ctx, PR_TRUE); | |
223 return rv; | |
224 } | |
wtc
2011/09/02 22:31:08
If these functions are copied from NSS or Mozilla,
zel
2011/09/03 01:52:22
Removed.
| |
225 #endif | |
226 | |
227 | |
wtc
2011/09/02 22:31:08
Nit: remove one blank line.
| |
86 // On non-chromeos platforms, return the default config directory. | 228 // On non-chromeos platforms, return the default config directory. |
87 // On chromeos, return a read-only directory with fake root CA certs for testing | 229 // On chromeos, return a read-only directory with fake root CA certs for testing |
88 // (which will not exist on non-testing images). These root CA certs are used | 230 // (which will not exist on non-testing images). These root CA certs are used |
89 // by the local Google Accounts server mock we use when testing our login code. | 231 // by the local Google Accounts server mock we use when testing our login code. |
90 // If this directory is not present, NSS_Init() will fail. It is up to the | 232 // If this directory is not present, NSS_Init() will fail. It is up to the |
91 // caller to failover to NSS_NoDB_Init() at that point. | 233 // caller to failover to NSS_NoDB_Init() at that point. |
92 FilePath GetInitialConfigDirectory() { | 234 FilePath GetInitialConfigDirectory() { |
93 #if defined(OS_CHROMEOS) | 235 #if defined(OS_CHROMEOS) |
94 return FilePath(kReadOnlyCertDB); | 236 return FilePath(kReadOnlyCertDB); |
95 #else | 237 #else |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 | 422 |
281 bool IsTPMTokenReady() { | 423 bool IsTPMTokenReady() { |
282 return tpm_slot_ != NULL; | 424 return tpm_slot_ != NULL; |
283 } | 425 } |
284 | 426 |
285 PK11SlotInfo* GetTPMSlot() { | 427 PK11SlotInfo* GetTPMSlot() { |
286 std::string token_name; | 428 std::string token_name; |
287 GetTPMTokenInfo(&token_name, NULL); | 429 GetTPMTokenInfo(&token_name, NULL); |
288 return FindSlotWithTokenName(token_name); | 430 return FindSlotWithTokenName(token_name); |
289 } | 431 } |
290 | 432 /* |
433 bool GetSupplementalUserKey(std::string* user_key) { | |
434 OpenPersistentNSSDB(); | |
435 | |
436 SECStatus rv = SECSuccess; | |
437 PK11SlotInfo* slot = NULL; | |
438 PK11SymKey *key = NULL; | |
439 SECItem* keyData = NULL; | |
440 SECItem keyID; | |
441 CK_MECHANISM_TYPE type = CKM_DES3_CBC; | |
442 PLArenaPool *arena = 0; | |
443 | |
444 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
445 if (!arena) | |
446 goto done; | |
447 | |
448 slot = GetPublicNSSKeySlot(); | |
449 if (!slot) { | |
450 rv = SECFailure; | |
451 goto done; | |
452 } | |
453 | |
454 rv = PK11_Authenticate(slot, PR_TRUE, NULL); | |
455 if (rv != SECSuccess) | |
456 goto done; | |
457 | |
458 keyID.type = siBuffer; | |
459 keyID.data = kSupplementalUserKeyId; | |
460 keyID.len = static_cast<int>(sizeof(kSupplementalUserKeyId)); | |
461 | |
462 // Find/generate AES key. | |
463 key = PK11_FindFixedKey(slot, type, &keyID, NULL); | |
464 if (!key) { | |
465 | |
466 key = PK11_TokenKeyGen(slot, type, 0, 0, &keyID, PR_TRUE, NULL); | |
467 if (key) { | |
468 rv = PK11_SetSymKeyNickname(key, kSupplementalKeyNickname); | |
469 if (rv != SECSuccess) | |
470 goto done; | |
471 } else { | |
472 int error = PORT_GetError(); | |
473 LOG(WARNING) << "Got error: " << error; | |
474 } | |
475 } | |
476 | |
477 if (!key) { | |
478 rv = SECFailure; | |
479 goto done; | |
480 } | |
481 | |
482 keyData = PK11_GetKeyData(key); | |
483 if (!keyData) { | |
484 rv = SECFailure; | |
485 goto done; | |
486 } | |
487 | |
488 *user_key = std::string( | |
489 reinterpret_cast<const char*>(keyData->data), keyData->len); | |
490 | |
491 done: | |
492 if (arena) | |
493 PORT_FreeArena(arena, PR_TRUE); | |
494 if (keyData) | |
495 SECITEM_ZfreeItem(keyData, PR_FALSE); | |
496 if (key) | |
497 PK11_FreeSymKey(key); | |
498 if (slot) | |
499 PK11_FreeSlot(slot); | |
500 | |
501 return (rv == SECSuccess); | |
502 } | |
503 */ | |
wtc
2011/09/02 22:31:08
Nit: please use #if 0 to comment out a block of co
zel
2011/09/03 01:52:22
Rewritten part.
| |
504 | |
505 bool EncryptWithSupplementalUserKey(const std::string& raw_data, | |
506 std::string* encryped_data) { | |
507 DCHECK(chromeos_user_logged_in_); | |
508 | |
509 SECStatus rv = SECSuccess; | |
510 SECItem *params = NULL; | |
511 PK11SlotInfo* slot = NULL; | |
512 PK11SymKey *key = NULL; | |
513 PLArenaPool *arena = 0; | |
514 PK11Context *ctx = 0; | |
515 SDRResult sdrResult; | |
516 SECItem keyID; | |
517 SECItem data; | |
518 SECItem paddedData = { siBuffer, NULL, 0 }; | |
519 SECItem tempResults = { siBuffer, NULL, 0 }; | |
520 CK_MECHANISM_TYPE type = CKM_AES_CBC; | |
521 | |
522 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
523 if (!arena) | |
524 goto done; | |
525 | |
526 slot = GetPublicNSSKeySlot(); | |
527 if (!slot) { | |
528 rv = SECFailure; | |
529 goto done; | |
530 } | |
531 | |
532 rv = PK11_Authenticate(slot, PR_TRUE, NULL); | |
533 if (rv != SECSuccess) | |
534 goto done; | |
535 | |
536 keyID.type = siBuffer; | |
537 keyID.data = kSupplementalUserKeyId; | |
538 keyID.len = static_cast<int>(sizeof(kSupplementalUserKeyId)); | |
539 | |
540 // Find/generate AES key. | |
541 key = PK11_FindFixedKey(slot, type, &keyID, NULL); | |
542 if (!key) { | |
543 key = PK11_TokenKeyGen(slot, type, NULL, | |
544 32, /* keysize in bytes*/ | |
wtc
2011/09/02 22:31:08
This is just a comment: 256-bit AES is extremely s
| |
545 &keyID, PR_TRUE, NULL); | |
546 if (key) { | |
547 rv = PK11_SetSymKeyNickname(key, kSupplementalKeyNickname); | |
548 if (rv != SECSuccess) | |
549 goto done; | |
550 } | |
551 } | |
552 if (!key) { | |
553 rv = SECFailure; | |
554 goto done; | |
555 } | |
556 | |
557 params = PK11_GenerateNewParam(type, key); | |
558 if (!params) { | |
559 rv = SECFailure; | |
560 goto done; | |
561 } | |
562 | |
563 ctx = PK11_CreateContextBySymKey(type, CKA_ENCRYPT, key, params); | |
564 if (!ctx) { | |
565 rv = SECFailure; | |
566 goto done; | |
567 } | |
568 | |
569 data.type = siBuffer; | |
570 data.data = reinterpret_cast<unsigned char*>( | |
571 const_cast<char*>(raw_data.c_str())); | |
572 data.len = static_cast<int>(raw_data.length()); | |
573 | |
574 rv = PadBlock(&data, PK11_GetBlockSize(type, 0), &paddedData); | |
575 if (rv != SECSuccess) | |
576 goto done; | |
577 | |
578 sdrResult.data.len = paddedData.len; | |
579 sdrResult.data.data = reinterpret_cast<unsigned char *>( | |
580 PORT_ArenaAlloc(arena, sdrResult.data.len)); | |
581 rv = PK11_CipherOp(ctx, sdrResult.data.data, | |
582 reinterpret_cast<int*>(&sdrResult.data.len), sdrResult.data.len, | |
583 paddedData.data, paddedData.len); | |
584 if (rv != SECSuccess) | |
585 goto done; | |
586 | |
587 PK11_Finalize(ctx); | |
588 sdrResult.keyid = keyID; | |
589 | |
590 rv = PK11_ParamToAlgid(SEC_OID_AES_256_CBC, params, arena, &sdrResult.alg); | |
591 if (rv != SECSuccess) | |
592 goto done; | |
593 | |
594 if (!SEC_ASN1EncodeItem(0, &tempResults, &sdrResult, g_encoding_template)) { | |
595 rv = SECFailure; | |
596 goto done; | |
597 } | |
598 | |
599 if (rv == SECSuccess) | |
600 *encryped_data = std::string( | |
601 reinterpret_cast<const char*>(tempResults.data), tempResults.len); | |
602 | |
603 done: | |
604 SECITEM_ZfreeItem(&paddedData, PR_FALSE); | |
605 SECITEM_ZfreeItem(&tempResults, PR_FALSE); | |
606 if (arena) | |
607 PORT_FreeArena(arena, PR_TRUE); | |
608 if (ctx) | |
609 PK11_DestroyContext(ctx, PR_TRUE); | |
610 if (params) | |
611 SECITEM_ZfreeItem(params, PR_TRUE); | |
612 if (key) | |
613 PK11_FreeSymKey(key); | |
614 if (slot) | |
615 PK11_FreeSlot(slot); | |
616 | |
617 return (rv == SECSuccess); | |
618 } | |
619 | |
620 bool DecryptWithSupplementalUserKey(const std::string& encrypted_data, | |
621 std::string* decrypted_data) { | |
622 DCHECK(chromeos_user_logged_in_); | |
623 | |
624 SECStatus rv = SECSuccess; | |
625 PK11SlotInfo *slot = 0; | |
626 PK11SymKey *key = 0; | |
627 CK_MECHANISM_TYPE type; | |
628 SDRResult sdrResult; | |
629 SECItem *params = 0; | |
630 SECItem result = { siBuffer, NULL, 0 }; | |
631 SECItem possibleResult = { siBuffer, NULL, 0 }; | |
632 PLArenaPool *arena = 0; | |
633 void* cx = NULL; | |
634 | |
635 SECItem data; | |
636 data.type = siBuffer; | |
637 data.data = reinterpret_cast<unsigned char*>( | |
638 const_cast<char*>(encrypted_data.c_str())); | |
639 data.len = static_cast<int>(encrypted_data.length()); | |
640 | |
641 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
642 if (!arena) { | |
643 rv = SECFailure; | |
644 goto done; | |
645 } | |
646 | |
647 // Decode the incoming data. | |
648 memset(&sdrResult, 0, sizeof sdrResult); | |
649 rv = SEC_QuickDERDecodeItem(arena, &sdrResult, g_encoding_template, &data); | |
650 if (rv != SECSuccess) // Invalid format. | |
651 goto done; | |
652 | |
653 // Find the slot and key for the given keyid. | |
654 slot = GetPublicNSSKeySlot(); | |
655 if (!slot) { | |
656 rv = SECFailure; | |
657 goto done; | |
658 } | |
659 | |
660 // Get the parameter values from the data. | |
661 params = PK11_ParamFromAlgid(&sdrResult.alg); | |
662 if (!params) { | |
663 rv = SECFailure; | |
664 goto done; | |
665 } | |
666 | |
667 // Use AES. | |
668 type = CKM_AES_CBC; | |
669 key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx); | |
670 if (!key) { | |
671 rv = SECFailure; | |
672 } else { | |
673 rv = pk11Decrypt(slot, arena, type, key, params, &sdrResult.data, | |
674 &result); | |
675 } | |
676 | |
677 // if the pad value was too small (1 or 2), then it's statistically | |
678 // 'likely' that (1 in 256) that we may not have the correct key. | |
679 // Check the other keys for a better match. If we find none, use | |
680 // this result. | |
681 if (rv == SECWouldBlock) | |
682 possibleResult = result; | |
683 | |
684 // handle the case where your key indicies may have been broken. | |
685 if (rv != SECSuccess) { | |
686 PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx); | |
687 PK11SymKey *testKey = NULL; | |
688 PK11SymKey *nextKey = NULL; | |
689 | |
690 for (testKey = keyList; testKey; testKey = PK11_GetNextSymKey(testKey)) { | |
691 rv = pk11Decrypt(slot, arena, type, testKey, params, | |
692 &sdrResult.data, &result); | |
693 if (rv == SECSuccess) | |
694 break; | |
695 | |
696 // found a close match. If it's our first remember it. | |
697 if (rv == SECWouldBlock) { | |
698 if (possibleResult.data) { | |
699 // this is unlikely but possible. If we hit this condition, | |
700 // we have no way of knowing which possibility to prefer. | |
701 // in this case we just match the key the application | |
702 // thought was the right one | |
703 SECITEM_ZfreeItem(&result, PR_FALSE); | |
704 } else { | |
705 possibleResult = result; | |
706 } | |
707 } | |
708 } | |
709 // free the list | |
710 for (testKey = keyList; testKey; testKey = nextKey) { | |
711 nextKey = PK11_GetNextSymKey(testKey); | |
712 PK11_FreeSymKey(testKey); | |
713 } | |
714 } | |
715 | |
716 // we didn't find a better key, use the one with a small pad value | |
717 if ((rv != SECSuccess) && (possibleResult.data)) { | |
718 result = possibleResult; | |
719 possibleResult.data = NULL; | |
720 rv = SECSuccess; | |
721 } | |
722 | |
723 if (rv == SECSuccess) { | |
724 *decrypted_data = std::string(reinterpret_cast<const char*>(result.data), | |
725 result.len); | |
726 } | |
727 | |
728 done: | |
729 SECITEM_ZfreeItem(&result, PR_FALSE); | |
730 if (arena) | |
731 PORT_FreeArena(arena, PR_TRUE); | |
732 if (key) | |
733 PK11_FreeSymKey(key); | |
734 if (params) | |
735 SECITEM_ZfreeItem(params, PR_TRUE); | |
736 if (slot) | |
737 PK11_FreeSlot(slot); | |
738 if (possibleResult.data) | |
739 SECITEM_ZfreeItem(&possibleResult, PR_FALSE); | |
740 | |
741 return (rv == SECSuccess); | |
742 } | |
291 #endif // defined(OS_CHROMEOS) | 743 #endif // defined(OS_CHROMEOS) |
292 | 744 |
293 | 745 |
294 bool OpenTestNSSDB(const FilePath& path, const char* description) { | 746 bool OpenTestNSSDB(const FilePath& path, const char* description) { |
295 test_slot_ = OpenUserDB(path, description); | 747 test_slot_ = OpenUserDB(path, description); |
296 return !!test_slot_; | 748 return !!test_slot_; |
297 } | 749 } |
298 | 750 |
299 void CloseTestNSSDB() { | 751 void CloseTestNSSDB() { |
300 if (test_slot_) { | 752 if (test_slot_) { |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 } | 1147 } |
696 | 1148 |
697 bool IsTPMTokenReady() { | 1149 bool IsTPMTokenReady() { |
698 return g_nss_singleton.Get().IsTPMTokenReady(); | 1150 return g_nss_singleton.Get().IsTPMTokenReady(); |
699 } | 1151 } |
700 | 1152 |
701 bool EnsureTPMTokenReady() { | 1153 bool EnsureTPMTokenReady() { |
702 return g_nss_singleton.Get().EnsureTPMTokenReady(); | 1154 return g_nss_singleton.Get().EnsureTPMTokenReady(); |
703 } | 1155 } |
704 | 1156 |
1157 bool EncryptWithSupplementalUserKey(const std::string& data, | |
1158 std::string* encryped_data) { | |
1159 return g_nss_singleton.Get().EncryptWithSupplementalUserKey(data, | |
1160 encryped_data); | |
1161 } | |
1162 | |
1163 bool DecryptWithSupplementalUserKey(const std::string& encryped_data, | |
1164 std::string* raw_data) { | |
1165 return g_nss_singleton.Get().DecryptWithSupplementalUserKey(encryped_data, | |
1166 raw_data); | |
1167 } | |
705 #endif // defined(OS_CHROMEOS) | 1168 #endif // defined(OS_CHROMEOS) |
706 | 1169 |
707 // TODO(port): Implement this more simply. We can convert by subtracting an | 1170 // TODO(port): Implement this more simply. We can convert by subtracting an |
708 // offset (the difference between NSPR's and base::Time's epochs). | 1171 // offset (the difference between NSPR's and base::Time's epochs). |
709 base::Time PRTimeToBaseTime(PRTime prtime) { | 1172 base::Time PRTimeToBaseTime(PRTime prtime) { |
710 PRExplodedTime prxtime; | 1173 PRExplodedTime prxtime; |
711 PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime); | 1174 PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime); |
712 | 1175 |
713 base::Time::Exploded exploded; | 1176 base::Time::Exploded exploded; |
714 exploded.year = prxtime.tm_year; | 1177 exploded.year = prxtime.tm_year; |
(...skipping 10 matching lines...) Expand all Loading... | |
725 | 1188 |
726 PK11SlotInfo* GetPublicNSSKeySlot() { | 1189 PK11SlotInfo* GetPublicNSSKeySlot() { |
727 return g_nss_singleton.Get().GetPublicNSSKeySlot(); | 1190 return g_nss_singleton.Get().GetPublicNSSKeySlot(); |
728 } | 1191 } |
729 | 1192 |
730 PK11SlotInfo* GetPrivateNSSKeySlot() { | 1193 PK11SlotInfo* GetPrivateNSSKeySlot() { |
731 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); | 1194 return g_nss_singleton.Get().GetPrivateNSSKeySlot(); |
732 } | 1195 } |
733 | 1196 |
734 } // namespace crypto | 1197 } // namespace crypto |
OLD | NEW |