1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 * This file manages Netscape specific PKCS #11 objects (CRLs, Trust objects,
65 extern const NSSError NSS_ERROR_NOT_FOUND
;
68 pk11_GetTrustField(PK11SlotInfo
*slot
, PRArenaPool
*arena
,
69 CK_OBJECT_HANDLE id
, CK_ATTRIBUTE_TYPE type
)
77 if( SECSuccess
== PK11_ReadAttribute(slot
, id
, type
, arena
, &item
) ) {
78 PORT_Assert(item
.len
== sizeof(CK_TRUST
));
79 PORT_Memcpy(&rv
, item
.data
, sizeof(CK_TRUST
));
80 /* Damn, is there an endian problem here? */
88 pk11_HandleTrustObject(PK11SlotInfo
*slot
, CERTCertificate
*cert
, CERTCertTrust
*trust
)
92 CK_ATTRIBUTE tobjTemplate
[] = {
93 { CKA_CLASS
, NULL
, 0 },
94 { CKA_CERT_SHA1_HASH
, NULL
, 0 },
97 CK_OBJECT_CLASS tobjc
= CKO_NETSCAPE_TRUST
;
98 CK_OBJECT_HANDLE tobjID
;
99 unsigned char sha1_hash
[SHA1_LENGTH
];
101 CK_TRUST serverAuth
, codeSigning
, emailProtection
, clientAuth
;
103 PK11_HashBuf(SEC_OID_SHA1
, sha1_hash
, cert
->derCert
.data
, cert
->derCert
.len
);
105 PK11_SETATTRS(&tobjTemplate
[0], CKA_CLASS
, &tobjc
, sizeof(tobjc
));
106 PK11_SETATTRS(&tobjTemplate
[1], CKA_CERT_SHA1_HASH
, sha1_hash
,
109 tobjID
= pk11_FindObjectByTemplate(slot
, tobjTemplate
,
110 sizeof(tobjTemplate
)/sizeof(tobjTemplate
[0]));
111 if( CK_INVALID_HANDLE
== tobjID
) {
115 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
116 if( NULL
== arena
) return PR_FALSE
;
118 /* Unfortunately, it seems that PK11_GetAttributes doesn't deal
119 * well with nonexistant attributes. I guess we have to check
120 * the trust info fields one at a time.
123 /* We could verify CKA_CERT_HASH here */
125 /* We could verify CKA_EXPIRES here */
128 /* "Purpose" trust information */
129 serverAuth
= pk11_GetTrustField(slot
, arena
, tobjID
, CKA_TRUST_SERVER_AUTH
);
130 clientAuth
= pk11_GetTrustField(slot
, arena
, tobjID
, CKA_TRUST_CLIENT_AUTH
);
131 codeSigning
= pk11_GetTrustField(slot
, arena
, tobjID
, CKA_TRUST_CODE_SIGNING
);
132 emailProtection
= pk11_GetTrustField(slot
, arena
, tobjID
,
133 CKA_TRUST_EMAIL_PROTECTION
);
134 /* Here's where the fun logic happens. We have to map back from the
135 * key usage, extended key usage, purpose, and possibly other trust values
136 * into the old trust-flags bits. */
138 /* First implementation: keep it simple for testing. We can study what other
139 * mappings would be appropriate and add them later.. fgmr 20000724 */
141 if ( serverAuth
== CKT_NETSCAPE_TRUSTED
) {
142 trust
->sslFlags
|= CERTDB_VALID_PEER
| CERTDB_TRUSTED
;
145 if ( serverAuth
== CKT_NETSCAPE_TRUSTED_DELEGATOR
) {
146 trust
->sslFlags
|= CERTDB_VALID_CA
| CERTDB_TRUSTED_CA
|
147 CERTDB_NS_TRUSTED_CA
;
149 if ( clientAuth
== CKT_NETSCAPE_TRUSTED_DELEGATOR
) {
150 trust
->sslFlags
|= CERTDB_TRUSTED_CLIENT_CA
;
153 if ( emailProtection
== CKT_NETSCAPE_TRUSTED
) {
154 trust
->emailFlags
|= CERTDB_VALID_PEER
| CERTDB_TRUSTED
;
157 if ( emailProtection
== CKT_NETSCAPE_TRUSTED_DELEGATOR
) {
158 trust
->emailFlags
|= CERTDB_VALID_CA
| CERTDB_TRUSTED_CA
| CERTDB_NS_TRUSTED_CA
;
161 if( codeSigning
== CKT_NETSCAPE_TRUSTED
) {
162 trust
->objectSigningFlags
|= CERTDB_VALID_PEER
| CERTDB_TRUSTED
;
165 if( codeSigning
== CKT_NETSCAPE_TRUSTED_DELEGATOR
) {
166 trust
->objectSigningFlags
|= CERTDB_VALID_CA
| CERTDB_TRUSTED_CA
| CERTDB_NS_TRUSTED_CA
;
169 /* There's certainly a lot more logic that can go here.. */
171 PORT_FreeArena(arena
, PR_FALSE
);
177 pk11_CollectCrls(PK11SlotInfo
*slot
, CK_OBJECT_HANDLE crlID
, void *arg
)
180 CERTCrlHeadNode
*head
= (CERTCrlHeadNode
*) arg
;
181 CERTCrlNode
*new_node
= NULL
;
182 CK_ATTRIBUTE fetchCrl
[3] = {
183 { CKA_VALUE
, NULL
, 0},
184 { CKA_NETSCAPE_KRL
, NULL
, 0},
185 { CKA_NETSCAPE_URL
, NULL
, 0},
187 const int fetchCrlSize
= sizeof(fetchCrl
)/sizeof(fetchCrl
[2]);
189 SECStatus rv
= SECFailure
;
191 crv
= PK11_GetAttributes(head
->arena
,slot
,crlID
,fetchCrl
,fetchCrlSize
);
193 PORT_SetError(PK11_MapError(crv
));
197 if (!fetchCrl
[1].pValue
) {
198 PORT_SetError(SEC_ERROR_CRL_INVALID
);
202 new_node
= (CERTCrlNode
*)PORT_ArenaAlloc(head
->arena
, sizeof(CERTCrlNode
));
203 if (new_node
== NULL
) {
207 if (*((CK_BBOOL
*)fetchCrl
[1].pValue
))
208 new_node
->type
= SEC_KRL_TYPE
;
210 new_node
->type
= SEC_CRL_TYPE
;
212 derCrl
.type
= siBuffer
;
213 derCrl
.data
= (unsigned char *)fetchCrl
[0].pValue
;
214 derCrl
.len
= fetchCrl
[0].ulValueLen
;
215 new_node
->crl
=CERT_DecodeDERCrl(head
->arena
,&derCrl
,new_node
->type
);
216 if (new_node
->crl
== NULL
) {
220 if (fetchCrl
[2].pValue
) {
221 int nnlen
= fetchCrl
[2].ulValueLen
;
222 new_node
->crl
->url
= (char *)PORT_ArenaAlloc(head
->arena
, nnlen
+1);
223 if ( !new_node
->crl
->url
) {
226 PORT_Memcpy(new_node
->crl
->url
, fetchCrl
[2].pValue
, nnlen
);
227 new_node
->crl
->url
[nnlen
] = 0;
229 new_node
->crl
->url
= NULL
;
233 new_node
->next
= NULL
;
235 head
->last
->next
= new_node
;
236 head
->last
= new_node
;
238 head
->first
= head
->last
= new_node
;
247 * Return a list of all the CRLs .
248 * CRLs are allocated in the list's arena.
251 PK11_LookupCrls(CERTCrlHeadNode
*nodes
, int type
, void *wincx
) {
252 pk11TraverseSlot creater
;
253 CK_ATTRIBUTE theTemplate
[2];
255 CK_OBJECT_CLASS certClass
= CKO_NETSCAPE_CRL
;
256 CK_BBOOL isKrl
= CK_FALSE
;
259 PK11_SETATTRS(attrs
, CKA_CLASS
, &certClass
, sizeof(certClass
)); attrs
++;
261 isKrl
= (CK_BBOOL
) (type
== SEC_KRL_TYPE
);
262 PK11_SETATTRS(attrs
, CKA_NETSCAPE_KRL
, &isKrl
, sizeof(isKrl
)); attrs
++;
265 creater
.callback
= pk11_CollectCrls
;
266 creater
.callbackArg
= (void *) nodes
;
267 creater
.findTemplate
= theTemplate
;
268 creater
.templateCount
= (attrs
- theTemplate
);
270 return pk11_TraverseAllSlots(PK11_TraverseSlot
, &creater
, PR_FALSE
, wincx
);
273 struct crlOptionsStr
{
274 CERTCrlHeadNode
* head
;
275 PRInt32 decodeOptions
;
278 typedef struct crlOptionsStr crlOptions
;
281 pk11_RetrieveCrlsCallback(PK11SlotInfo
*slot
, CK_OBJECT_HANDLE crlID
,
284 SECItem
* derCrl
= NULL
;
285 crlOptions
* options
= (crlOptions
*) arg
;
286 CERTCrlHeadNode
*head
= options
->head
;
287 CERTCrlNode
*new_node
= NULL
;
288 CK_ATTRIBUTE fetchCrl
[3] = {
289 { CKA_VALUE
, NULL
, 0},
290 { CKA_NETSCAPE_KRL
, NULL
, 0},
291 { CKA_NETSCAPE_URL
, NULL
, 0},
293 const int fetchCrlSize
= sizeof(fetchCrl
)/sizeof(fetchCrl
[2]);
295 SECStatus rv
= SECFailure
;
296 PRBool adopted
= PR_FALSE
; /* whether the CRL adopted the DER memory
300 crv
= PK11_GetAttributes(NULL
,slot
,crlID
,fetchCrl
,fetchCrlSize
);
302 PORT_SetError(PK11_MapError(crv
));
306 if (!fetchCrl
[1].pValue
) {
308 PORT_SetError(SEC_ERROR_CRL_INVALID
);
312 new_node
= (CERTCrlNode
*)PORT_ArenaAlloc(head
->arena
,
313 sizeof(CERTCrlNode
));
314 if (new_node
== NULL
) {
318 new_node
->type
= SEC_CRL_TYPE
;
320 derCrl
= SECITEM_AllocItem(NULL
, NULL
, 0);
324 derCrl
->type
= siBuffer
;
325 derCrl
->data
= (unsigned char *)fetchCrl
[0].pValue
;
326 derCrl
->len
= fetchCrl
[0].ulValueLen
;
327 new_node
->crl
= CERT_DecodeDERCrlWithFlags(NULL
, derCrl
,new_node
->type
,
328 options
->decodeOptions
);
329 if (new_node
->crl
== NULL
) {
332 adopted
= PR_TRUE
; /* now that the CRL has adopted the DER memory,
333 we won't need to free it upon exit */
335 if (fetchCrl
[2].pValue
&& fetchCrl
[2].ulValueLen
) {
336 /* copy the URL if there is one */
337 int nnlen
= fetchCrl
[2].ulValueLen
;
338 new_node
->crl
->url
= (char *)PORT_ArenaAlloc(new_node
->crl
->arena
,
340 if ( !new_node
->crl
->url
) {
343 PORT_Memcpy(new_node
->crl
->url
, fetchCrl
[2].pValue
, nnlen
);
344 new_node
->crl
->url
[nnlen
] = 0;
346 new_node
->crl
->url
= NULL
;
349 new_node
->next
= NULL
;
351 head
->last
->next
= new_node
;
352 head
->last
= new_node
;
354 head
->first
= head
->last
= new_node
;
357 new_node
->crl
->slot
= PK11_ReferenceSlot(slot
);
358 new_node
->crl
->pkcs11ID
= crlID
;
361 /* free attributes that weren't adopted by the CRL */
362 for (i
=1;i
<fetchCrlSize
;i
++) {
363 if (fetchCrl
[i
].pValue
) {
364 PORT_Free(fetchCrl
[i
].pValue
);
367 /* free the DER if the CRL object didn't adopt it */
368 if (fetchCrl
[0].pValue
&& PR_FALSE
== adopted
) {
369 PORT_Free(fetchCrl
[0].pValue
);
371 if (derCrl
&& !adopted
) {
372 /* clear the data fields, which we already took care of above */
375 /* free the memory for the SECItem structure itself */
376 SECITEM_FreeItem(derCrl
, PR_TRUE
);
382 * Return a list of CRLs matching specified issuer and type
383 * CRLs are not allocated in the list's arena, but rather in their own,
384 * arena, so that they can be used individually in the CRL cache .
385 * CRLs are always partially decoded for efficiency.
387 SECStatus
pk11_RetrieveCrls(CERTCrlHeadNode
*nodes
, SECItem
* issuer
,
390 pk11TraverseSlot creater
;
391 CK_ATTRIBUTE theTemplate
[2];
393 CK_OBJECT_CLASS crlClass
= CKO_NETSCAPE_CRL
;
397 PK11_SETATTRS(attrs
, CKA_CLASS
, &crlClass
, sizeof(crlClass
)); attrs
++;
399 options
.head
= nodes
;
401 /* - do a partial decoding - we don't need to decode the entries while
403 - don't copy the DER for optimal performance - CRL can be very large
404 - have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
405 - keep bad CRL objects. The CRL cache is interested in them, for
406 security purposes. Bad CRL objects are a sign of something amiss.
409 options
.decodeOptions
= CRL_DECODE_SKIP_ENTRIES
| CRL_DECODE_DONT_COPY_DER
|
410 CRL_DECODE_ADOPT_HEAP_DER
| CRL_DECODE_KEEP_BAD_CRL
;
413 PK11_SETATTRS(attrs
, CKA_SUBJECT
, issuer
->data
, issuer
->len
); attrs
++;
416 creater
.callback
= pk11_RetrieveCrlsCallback
;
417 creater
.callbackArg
= (void *) &options
;
418 creater
.findTemplate
= theTemplate
;
419 creater
.templateCount
= (attrs
- theTemplate
);
421 return pk11_TraverseAllSlots(PK11_TraverseSlot
, &creater
, PR_FALSE
, wincx
);
425 * return the crl associated with a derSubjectName
428 PK11_FindCrlByName(PK11SlotInfo
**slot
, CK_OBJECT_HANDLE
*crlHandle
,
429 SECItem
*name
, int type
, char **pUrl
)
431 NSSCRL
**crls
, **crlp
, *crl
= NULL
;
434 NSSTrustDomain
*td
= STAN_GetDefaultTrustDomain();
438 NSSITEM_FROM_SECITEM(&subject
, name
);
440 nssCryptokiObject
**instances
;
441 nssPKIObjectCollection
*collection
;
442 nssTokenSearchType tokenOnly
= nssTokenSearchType_TokenOnly
;
443 NSSToken
*token
= PK11Slot_GetNSSToken(*slot
);
444 collection
= nssCRLCollection_Create(td
, NULL
);
448 instances
= nssToken_FindCRLsBySubject(token
, NULL
, &subject
,
450 nssPKIObjectCollection_AddInstances(collection
, instances
, 0);
451 nss_ZFreeIf(instances
);
452 crls
= nssPKIObjectCollection_GetCRLs(collection
, NULL
, 0, NULL
);
453 nssPKIObjectCollection_Destroy(collection
);
455 crls
= nssTrustDomain_FindCRLsBySubject(td
, &subject
);
457 if ((!crls
) || (*crls
== NULL
)) {
459 nssCRLArray_Destroy(crls
);
461 if (NSS_GetError() == NSS_ERROR_NOT_FOUND
) {
462 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND
);
466 for (crlp
= crls
; *crlp
; crlp
++) {
467 if ((!(*crlp
)->isKRL
&& type
== SEC_CRL_TYPE
) ||
468 ((*crlp
)->isKRL
&& type
!= SEC_CRL_TYPE
))
470 crl
= nssCRL_AddRef(*crlp
);
474 nssCRLArray_Destroy(crls
);
476 /* CRL collection was found, but no interesting CRL's were on it.
478 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND
);
482 url
= PORT_Strdup(crl
->url
);
487 rvItem
= SECITEM_AllocItem(NULL
, NULL
, crl
->encoding
.size
);
491 memcpy(rvItem
->data
, crl
->encoding
.data
, crl
->encoding
.size
);
492 *slot
= PK11_ReferenceSlot(crl
->object
.instances
[0]->token
->pk11slot
);
493 *crlHandle
= crl
->object
.instances
[0]->handle
;
503 if (PORT_GetError() == 0) {
504 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND
);
510 PK11_PutCrl(PK11SlotInfo
*slot
, SECItem
*crl
, SECItem
*name
,
513 NSSItem derCRL
, derSubject
;
514 NSSToken
*token
= PK11Slot_GetNSSToken(slot
);
515 nssCryptokiObject
*object
;
516 PRBool isKRL
= (type
== SEC_CRL_TYPE
) ? PR_FALSE
: PR_TRUE
;
517 CK_OBJECT_HANDLE rvH
;
519 NSSITEM_FROM_SECITEM(&derSubject
, name
);
520 NSSITEM_FROM_SECITEM(&derCRL
, crl
);
522 object
= nssToken_ImportCRL(token
, NULL
,
523 &derSubject
, &derCRL
, isKRL
, url
, PR_TRUE
);
526 rvH
= object
->handle
;
527 nssCryptokiObject_Destroy(object
);
529 rvH
= CK_INVALID_HANDLE
;
539 SEC_DeletePermCRL(CERTSignedCrl
*crl
)
543 nssCryptokiObject
*object
;
544 PK11SlotInfo
*slot
= crl
->slot
;
548 /* shouldn't happen */
549 PORT_SetError( SEC_ERROR_CRL_INVALID
);
552 token
= PK11Slot_GetNSSToken(slot
);
554 object
= nss_ZNEW(NULL
, nssCryptokiObject
);
558 object
->token
= nssToken_AddRef(token
);
559 object
->handle
= crl
->pkcs11ID
;
560 object
->isTokenObject
= PR_TRUE
;
562 status
= nssToken_DeleteStoredObject(object
);
564 nssCryptokiObject_Destroy(object
);
565 return (status
== PR_SUCCESS
) ? SECSuccess
: SECFailure
;
569 * return the certificate associated with a derCert
572 PK11_FindSMimeProfile(PK11SlotInfo
**slot
, char *emailAddr
,
573 SECItem
*name
, SECItem
**profileTime
)
575 CK_OBJECT_CLASS smimeClass
= CKO_NETSCAPE_SMIME
;
576 CK_ATTRIBUTE theTemplate
[] = {
577 { CKA_SUBJECT
, NULL
, 0 },
578 { CKA_CLASS
, NULL
, 0 },
579 { CKA_NETSCAPE_EMAIL
, NULL
, 0 },
581 CK_ATTRIBUTE smimeData
[] = {
582 { CKA_SUBJECT
, NULL
, 0 },
583 { CKA_VALUE
, NULL
, 0 },
585 /* if you change the array, change the variable below as well */
586 int tsize
= sizeof(theTemplate
)/sizeof(theTemplate
[0]);
587 CK_OBJECT_HANDLE smimeh
= CK_INVALID_HANDLE
;
588 CK_ATTRIBUTE
*attrs
= theTemplate
;
590 SECItem
*emailProfile
= NULL
;
592 if (!emailAddr
|| !emailAddr
[0]) {
593 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
597 PK11_SETATTRS(attrs
, CKA_SUBJECT
, name
->data
, name
->len
); attrs
++;
598 PK11_SETATTRS(attrs
, CKA_CLASS
, &smimeClass
, sizeof(smimeClass
)); attrs
++;
599 PK11_SETATTRS(attrs
, CKA_NETSCAPE_EMAIL
, emailAddr
, strlen(emailAddr
));
603 smimeh
= pk11_FindObjectByTemplate(*slot
,theTemplate
,tsize
);
605 PK11SlotList
*list
= PK11_GetAllTokens(CKM_INVALID_MECHANISM
,
606 PR_FALSE
,PR_TRUE
,NULL
);
607 PK11SlotListElement
*le
;
612 /* loop through all the slots */
613 for (le
= list
->head
; le
; le
= le
->next
) {
614 smimeh
= pk11_FindObjectByTemplate(le
->slot
,theTemplate
,tsize
);
615 if (smimeh
!= CK_INVALID_HANDLE
) {
616 *slot
= PK11_ReferenceSlot(le
->slot
);
620 PK11_FreeSlotList(list
);
623 if (smimeh
== CK_INVALID_HANDLE
) {
624 PORT_SetError(SEC_ERROR_NO_KRL
);
629 PK11_SETATTRS(smimeData
, CKA_NETSCAPE_SMIME_TIMESTAMP
, NULL
, 0);
632 crv
= PK11_GetAttributes(NULL
,*slot
,smimeh
,smimeData
,2);
634 PORT_SetError(PK11_MapError (crv
));
639 SECItem profileSubject
;
641 profileSubject
.data
= (unsigned char*) smimeData
[0].pValue
;
642 profileSubject
.len
= smimeData
[0].ulValueLen
;
643 if (!SECITEM_ItemsAreEqual(&profileSubject
,name
)) {
648 emailProfile
= (SECItem
*)PORT_ZAlloc(sizeof(SECItem
));
649 if (emailProfile
== NULL
) {
653 emailProfile
->data
= (unsigned char*) smimeData
[1].pValue
;
654 emailProfile
->len
= smimeData
[1].ulValueLen
;
657 *profileTime
= (SECItem
*)PORT_ZAlloc(sizeof(SECItem
));
659 (*profileTime
)->data
= (unsigned char*) smimeData
[0].pValue
;
660 (*profileTime
)->len
= smimeData
[0].ulValueLen
;
665 if (emailProfile
== NULL
) {
666 if (smimeData
[1].pValue
) {
667 PORT_Free(smimeData
[1].pValue
);
670 if (profileTime
== NULL
|| *profileTime
== NULL
) {
671 if (smimeData
[0].pValue
) {
672 PORT_Free(smimeData
[0].pValue
);
680 PK11_SaveSMimeProfile(PK11SlotInfo
*slot
, char *emailAddr
, SECItem
*derSubj
,
681 SECItem
*emailProfile
, SECItem
*profileTime
)
683 CK_OBJECT_CLASS smimeClass
= CKO_NETSCAPE_SMIME
;
684 CK_BBOOL ck_true
= CK_TRUE
;
685 CK_ATTRIBUTE theTemplate
[] = {
686 { CKA_CLASS
, NULL
, 0 },
687 { CKA_TOKEN
, NULL
, 0 },
688 { CKA_SUBJECT
, NULL
, 0 },
689 { CKA_NETSCAPE_EMAIL
, NULL
, 0 },
690 { CKA_NETSCAPE_SMIME_TIMESTAMP
, NULL
, 0 },
691 { CKA_VALUE
, NULL
, 0 }
693 /* if you change the array, change the variable below as well */
695 CK_OBJECT_HANDLE smimeh
= CK_INVALID_HANDLE
;
696 CK_ATTRIBUTE
*attrs
= theTemplate
;
697 CK_SESSION_HANDLE rwsession
;
698 PK11SlotInfo
*free_slot
= NULL
;
701 int tsize
= sizeof(theTemplate
)/sizeof(theTemplate
[0]);
704 PK11_SETATTRS(attrs
, CKA_CLASS
, &smimeClass
, sizeof(smimeClass
)); attrs
++;
705 PK11_SETATTRS(attrs
, CKA_TOKEN
, &ck_true
, sizeof(ck_true
)); attrs
++;
706 PK11_SETATTRS(attrs
, CKA_SUBJECT
, derSubj
->data
, derSubj
->len
); attrs
++;
707 PK11_SETATTRS(attrs
, CKA_NETSCAPE_EMAIL
,
708 emailAddr
, PORT_Strlen(emailAddr
)+1); attrs
++;
710 PK11_SETATTRS(attrs
, CKA_NETSCAPE_SMIME_TIMESTAMP
, profileTime
->data
,
711 profileTime
->len
); attrs
++;
712 PK11_SETATTRS(attrs
, CKA_VALUE
,emailProfile
->data
,
713 emailProfile
->len
); attrs
++;
715 realSize
= attrs
- theTemplate
;
716 PORT_Assert (realSize
<= tsize
);
719 free_slot
= slot
= PK11_GetInternalKeySlot();
720 /* we need to free the key slot in the end!!! */
723 rwsession
= PK11_GetRWSession(slot
);
724 if (rwsession
== CK_INVALID_SESSION
) {
725 PORT_SetError(SEC_ERROR_READ_ONLY
);
727 PK11_FreeSlot(free_slot
);
732 crv
= PK11_GETTAB(slot
)->
733 C_CreateObject(rwsession
,theTemplate
,realSize
,&smimeh
);
735 PORT_SetError( PK11_MapError(crv
) );
738 PK11_RestoreROSession(slot
,rwsession
);
741 PK11_FreeSlot(free_slot
);
747 CERTSignedCrl
* crl_storeCRL (PK11SlotInfo
*slot
,char *url
,
748 CERTSignedCrl
*newCrl
, SECItem
*derCrl
, int type
);
750 /* import the CRL into the token */
752 CERTSignedCrl
* PK11_ImportCRL(PK11SlotInfo
* slot
, SECItem
*derCRL
, char *url
,
753 int type
, void *wincx
, PRInt32 importOptions
, PRArenaPool
* arena
,
754 PRInt32 decodeoptions
)
756 CERTSignedCrl
*newCrl
, *crl
;
758 CERTCertificate
*caCert
= NULL
;
763 newCrl
= CERT_DecodeDERCrlWithFlags(arena
, derCRL
, type
,
765 if (newCrl
== NULL
) {
766 if (type
== SEC_CRL_TYPE
) {
767 /* only promote error when the error code is too generic */
768 if (PORT_GetError () == SEC_ERROR_BAD_DER
)
769 PORT_SetError(SEC_ERROR_CRL_INVALID
);
771 PORT_SetError(SEC_ERROR_KRL_INVALID
);
776 if (0 == (importOptions
& CRL_IMPORT_BYPASS_CHECKS
)){
777 CERTCertDBHandle
* handle
= CERT_GetDefaultCertDB();
778 PR_ASSERT(handle
!= NULL
);
779 caCert
= CERT_FindCertByName (handle
,
780 &newCrl
->crl
.derName
);
781 if (caCert
== NULL
) {
782 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER
);
786 /* If caCert is a v3 certificate, make sure that it can be used for
787 crl signing purpose */
788 rv
= CERT_CheckCertUsage (caCert
, KU_CRL_SIGN
);
789 if (rv
!= SECSuccess
) {
793 rv
= CERT_VerifySignedData(&newCrl
->signatureWrap
, caCert
,
795 if (rv
!= SECSuccess
) {
796 if (type
== SEC_CRL_TYPE
) {
797 PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE
);
799 PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE
);
805 crl
= crl_storeCRL(slot
, url
, newCrl
, derCRL
, type
);
810 SEC_DestroyCrl (newCrl
);
813 CERT_DestroyCertificate(caCert
);