Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include "pkcs11.h" |
michael@0 | 6 | |
michael@0 | 7 | #ifndef DEVM_H |
michael@0 | 8 | #include "devm.h" |
michael@0 | 9 | #endif /* DEVM_H */ |
michael@0 | 10 | |
michael@0 | 11 | #ifndef CKHELPER_H |
michael@0 | 12 | #include "ckhelper.h" |
michael@0 | 13 | #endif /* CKHELPER_H */ |
michael@0 | 14 | |
michael@0 | 15 | extern const NSSError NSS_ERROR_DEVICE_ERROR; |
michael@0 | 16 | |
michael@0 | 17 | static const CK_BBOOL s_true = CK_TRUE; |
michael@0 | 18 | NSS_IMPLEMENT_DATA const NSSItem |
michael@0 | 19 | g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) }; |
michael@0 | 20 | |
michael@0 | 21 | static const CK_BBOOL s_false = CK_FALSE; |
michael@0 | 22 | NSS_IMPLEMENT_DATA const NSSItem |
michael@0 | 23 | g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) }; |
michael@0 | 24 | |
michael@0 | 25 | static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE; |
michael@0 | 26 | NSS_IMPLEMENT_DATA const NSSItem |
michael@0 | 27 | g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) }; |
michael@0 | 28 | |
michael@0 | 29 | static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY; |
michael@0 | 30 | NSS_IMPLEMENT_DATA const NSSItem |
michael@0 | 31 | g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) }; |
michael@0 | 32 | |
michael@0 | 33 | static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY; |
michael@0 | 34 | NSS_IMPLEMENT_DATA const NSSItem |
michael@0 | 35 | g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) }; |
michael@0 | 36 | |
michael@0 | 37 | static PRBool |
michael@0 | 38 | is_string_attribute ( |
michael@0 | 39 | CK_ATTRIBUTE_TYPE aType |
michael@0 | 40 | ) |
michael@0 | 41 | { |
michael@0 | 42 | PRBool isString; |
michael@0 | 43 | switch (aType) { |
michael@0 | 44 | case CKA_LABEL: |
michael@0 | 45 | case CKA_NSS_EMAIL: |
michael@0 | 46 | isString = PR_TRUE; |
michael@0 | 47 | break; |
michael@0 | 48 | default: |
michael@0 | 49 | isString = PR_FALSE; |
michael@0 | 50 | break; |
michael@0 | 51 | } |
michael@0 | 52 | return isString; |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | NSS_IMPLEMENT PRStatus |
michael@0 | 56 | nssCKObject_GetAttributes ( |
michael@0 | 57 | CK_OBJECT_HANDLE object, |
michael@0 | 58 | CK_ATTRIBUTE_PTR obj_template, |
michael@0 | 59 | CK_ULONG count, |
michael@0 | 60 | NSSArena *arenaOpt, |
michael@0 | 61 | nssSession *session, |
michael@0 | 62 | NSSSlot *slot |
michael@0 | 63 | ) |
michael@0 | 64 | { |
michael@0 | 65 | nssArenaMark *mark = NULL; |
michael@0 | 66 | CK_SESSION_HANDLE hSession; |
michael@0 | 67 | CK_ULONG i = 0; |
michael@0 | 68 | CK_RV ckrv; |
michael@0 | 69 | PRStatus nssrv; |
michael@0 | 70 | PRBool alloced = PR_FALSE; |
michael@0 | 71 | void *epv = nssSlot_GetCryptokiEPV(slot); |
michael@0 | 72 | hSession = session->handle; |
michael@0 | 73 | if (arenaOpt) { |
michael@0 | 74 | mark = nssArena_Mark(arenaOpt); |
michael@0 | 75 | if (!mark) { |
michael@0 | 76 | goto loser; |
michael@0 | 77 | } |
michael@0 | 78 | } |
michael@0 | 79 | nssSession_EnterMonitor(session); |
michael@0 | 80 | /* XXX kinda hacky, if the storage size is already in the first template |
michael@0 | 81 | * item, then skip the alloc portion |
michael@0 | 82 | */ |
michael@0 | 83 | if (obj_template[0].ulValueLen == 0) { |
michael@0 | 84 | /* Get the storage size needed for each attribute */ |
michael@0 | 85 | ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, |
michael@0 | 86 | object, obj_template, count); |
michael@0 | 87 | if (ckrv != CKR_OK && |
michael@0 | 88 | ckrv != CKR_ATTRIBUTE_TYPE_INVALID && |
michael@0 | 89 | ckrv != CKR_ATTRIBUTE_SENSITIVE) |
michael@0 | 90 | { |
michael@0 | 91 | nssSession_ExitMonitor(session); |
michael@0 | 92 | nss_SetError(NSS_ERROR_DEVICE_ERROR); |
michael@0 | 93 | goto loser; |
michael@0 | 94 | } |
michael@0 | 95 | /* Allocate memory for each attribute. */ |
michael@0 | 96 | for (i=0; i<count; i++) { |
michael@0 | 97 | CK_ULONG ulValueLen = obj_template[i].ulValueLen; |
michael@0 | 98 | if (ulValueLen == 0 || ulValueLen == (CK_ULONG) -1) { |
michael@0 | 99 | obj_template[i].pValue = NULL; |
michael@0 | 100 | obj_template[i].ulValueLen = 0; |
michael@0 | 101 | continue; |
michael@0 | 102 | } |
michael@0 | 103 | if (is_string_attribute(obj_template[i].type)) { |
michael@0 | 104 | ulValueLen++; |
michael@0 | 105 | } |
michael@0 | 106 | obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen); |
michael@0 | 107 | if (!obj_template[i].pValue) { |
michael@0 | 108 | nssSession_ExitMonitor(session); |
michael@0 | 109 | goto loser; |
michael@0 | 110 | } |
michael@0 | 111 | } |
michael@0 | 112 | alloced = PR_TRUE; |
michael@0 | 113 | } |
michael@0 | 114 | /* Obtain the actual attribute values. */ |
michael@0 | 115 | ckrv = CKAPI(epv)->C_GetAttributeValue(hSession, |
michael@0 | 116 | object, obj_template, count); |
michael@0 | 117 | nssSession_ExitMonitor(session); |
michael@0 | 118 | if (ckrv != CKR_OK && |
michael@0 | 119 | ckrv != CKR_ATTRIBUTE_TYPE_INVALID && |
michael@0 | 120 | ckrv != CKR_ATTRIBUTE_SENSITIVE) |
michael@0 | 121 | { |
michael@0 | 122 | nss_SetError(NSS_ERROR_DEVICE_ERROR); |
michael@0 | 123 | goto loser; |
michael@0 | 124 | } |
michael@0 | 125 | if (alloced && arenaOpt) { |
michael@0 | 126 | nssrv = nssArena_Unmark(arenaOpt, mark); |
michael@0 | 127 | if (nssrv != PR_SUCCESS) { |
michael@0 | 128 | goto loser; |
michael@0 | 129 | } |
michael@0 | 130 | } |
michael@0 | 131 | |
michael@0 | 132 | if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || |
michael@0 | 133 | (ckrv == CKR_ATTRIBUTE_SENSITIVE))) { |
michael@0 | 134 | /* old tokens would keep the length of '0' and not deal with any |
michael@0 | 135 | * of the attributes we passed. For those tokens read them one at |
michael@0 | 136 | * a time */ |
michael@0 | 137 | for (i=0; i < count; i++) { |
michael@0 | 138 | if ((obj_template[i].ulValueLen == 0) |
michael@0 | 139 | || (obj_template[i].ulValueLen == -1)) { |
michael@0 | 140 | obj_template[i].ulValueLen=0; |
michael@0 | 141 | (void) nssCKObject_GetAttributes(object,&obj_template[i], 1, |
michael@0 | 142 | arenaOpt, session, slot); |
michael@0 | 143 | } |
michael@0 | 144 | } |
michael@0 | 145 | } |
michael@0 | 146 | return PR_SUCCESS; |
michael@0 | 147 | loser: |
michael@0 | 148 | if (alloced) { |
michael@0 | 149 | if (arenaOpt) { |
michael@0 | 150 | /* release all arena memory allocated before the failure. */ |
michael@0 | 151 | (void)nssArena_Release(arenaOpt, mark); |
michael@0 | 152 | } else { |
michael@0 | 153 | CK_ULONG j; |
michael@0 | 154 | /* free each heap object that was allocated before the failure. */ |
michael@0 | 155 | for (j=0; j<i; j++) { |
michael@0 | 156 | nss_ZFreeIf(obj_template[j].pValue); |
michael@0 | 157 | } |
michael@0 | 158 | } |
michael@0 | 159 | } |
michael@0 | 160 | return PR_FAILURE; |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | NSS_IMPLEMENT PRStatus |
michael@0 | 164 | nssCKObject_GetAttributeItem ( |
michael@0 | 165 | CK_OBJECT_HANDLE object, |
michael@0 | 166 | CK_ATTRIBUTE_TYPE attribute, |
michael@0 | 167 | NSSArena *arenaOpt, |
michael@0 | 168 | nssSession *session, |
michael@0 | 169 | NSSSlot *slot, |
michael@0 | 170 | NSSItem *rvItem |
michael@0 | 171 | ) |
michael@0 | 172 | { |
michael@0 | 173 | CK_ATTRIBUTE attr = { 0, NULL, 0 }; |
michael@0 | 174 | PRStatus nssrv; |
michael@0 | 175 | attr.type = attribute; |
michael@0 | 176 | nssrv = nssCKObject_GetAttributes(object, &attr, 1, |
michael@0 | 177 | arenaOpt, session, slot); |
michael@0 | 178 | if (nssrv != PR_SUCCESS) { |
michael@0 | 179 | return nssrv; |
michael@0 | 180 | } |
michael@0 | 181 | rvItem->data = (void *)attr.pValue; |
michael@0 | 182 | rvItem->size = (PRUint32)attr.ulValueLen; |
michael@0 | 183 | return PR_SUCCESS; |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | NSS_IMPLEMENT PRBool |
michael@0 | 187 | nssCKObject_IsAttributeTrue ( |
michael@0 | 188 | CK_OBJECT_HANDLE object, |
michael@0 | 189 | CK_ATTRIBUTE_TYPE attribute, |
michael@0 | 190 | nssSession *session, |
michael@0 | 191 | NSSSlot *slot, |
michael@0 | 192 | PRStatus *rvStatus |
michael@0 | 193 | ) |
michael@0 | 194 | { |
michael@0 | 195 | CK_BBOOL bool; |
michael@0 | 196 | CK_ATTRIBUTE_PTR attr; |
michael@0 | 197 | CK_ATTRIBUTE atemplate = { 0, NULL, 0 }; |
michael@0 | 198 | CK_RV ckrv; |
michael@0 | 199 | void *epv = nssSlot_GetCryptokiEPV(slot); |
michael@0 | 200 | attr = &atemplate; |
michael@0 | 201 | NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool); |
michael@0 | 202 | nssSession_EnterMonitor(session); |
michael@0 | 203 | ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object, |
michael@0 | 204 | &atemplate, 1); |
michael@0 | 205 | nssSession_ExitMonitor(session); |
michael@0 | 206 | if (ckrv != CKR_OK) { |
michael@0 | 207 | *rvStatus = PR_FAILURE; |
michael@0 | 208 | return PR_FALSE; |
michael@0 | 209 | } |
michael@0 | 210 | *rvStatus = PR_SUCCESS; |
michael@0 | 211 | return (PRBool)(bool == CK_TRUE); |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | NSS_IMPLEMENT PRStatus |
michael@0 | 215 | nssCKObject_SetAttributes ( |
michael@0 | 216 | CK_OBJECT_HANDLE object, |
michael@0 | 217 | CK_ATTRIBUTE_PTR obj_template, |
michael@0 | 218 | CK_ULONG count, |
michael@0 | 219 | nssSession *session, |
michael@0 | 220 | NSSSlot *slot |
michael@0 | 221 | ) |
michael@0 | 222 | { |
michael@0 | 223 | CK_RV ckrv; |
michael@0 | 224 | void *epv = nssSlot_GetCryptokiEPV(slot); |
michael@0 | 225 | nssSession_EnterMonitor(session); |
michael@0 | 226 | ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object, |
michael@0 | 227 | obj_template, count); |
michael@0 | 228 | nssSession_ExitMonitor(session); |
michael@0 | 229 | if (ckrv == CKR_OK) { |
michael@0 | 230 | return PR_SUCCESS; |
michael@0 | 231 | } else { |
michael@0 | 232 | return PR_FAILURE; |
michael@0 | 233 | } |
michael@0 | 234 | } |
michael@0 | 235 | |
michael@0 | 236 | NSS_IMPLEMENT PRBool |
michael@0 | 237 | nssCKObject_IsTokenObjectTemplate ( |
michael@0 | 238 | CK_ATTRIBUTE_PTR objectTemplate, |
michael@0 | 239 | CK_ULONG otsize |
michael@0 | 240 | ) |
michael@0 | 241 | { |
michael@0 | 242 | CK_ULONG ul; |
michael@0 | 243 | for (ul=0; ul<otsize; ul++) { |
michael@0 | 244 | if (objectTemplate[ul].type == CKA_TOKEN) { |
michael@0 | 245 | return (*((CK_BBOOL*)objectTemplate[ul].pValue) == CK_TRUE); |
michael@0 | 246 | } |
michael@0 | 247 | } |
michael@0 | 248 | return PR_FALSE; |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | static NSSCertificateType |
michael@0 | 252 | nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) |
michael@0 | 253 | { |
michael@0 | 254 | CK_CERTIFICATE_TYPE ckCertType; |
michael@0 | 255 | if (!attrib->pValue) { |
michael@0 | 256 | /* default to PKIX */ |
michael@0 | 257 | return NSSCertificateType_PKIX; |
michael@0 | 258 | } |
michael@0 | 259 | ckCertType = *((CK_ULONG *)attrib->pValue); |
michael@0 | 260 | switch (ckCertType) { |
michael@0 | 261 | case CKC_X_509: |
michael@0 | 262 | return NSSCertificateType_PKIX; |
michael@0 | 263 | default: |
michael@0 | 264 | break; |
michael@0 | 265 | } |
michael@0 | 266 | return NSSCertificateType_Unknown; |
michael@0 | 267 | } |
michael@0 | 268 | |
michael@0 | 269 | /* incoming pointers must be valid */ |
michael@0 | 270 | NSS_IMPLEMENT PRStatus |
michael@0 | 271 | nssCryptokiCertificate_GetAttributes ( |
michael@0 | 272 | nssCryptokiObject *certObject, |
michael@0 | 273 | nssSession *sessionOpt, |
michael@0 | 274 | NSSArena *arenaOpt, |
michael@0 | 275 | NSSCertificateType *certTypeOpt, |
michael@0 | 276 | NSSItem *idOpt, |
michael@0 | 277 | NSSDER *encodingOpt, |
michael@0 | 278 | NSSDER *issuerOpt, |
michael@0 | 279 | NSSDER *serialOpt, |
michael@0 | 280 | NSSDER *subjectOpt |
michael@0 | 281 | ) |
michael@0 | 282 | { |
michael@0 | 283 | PRStatus status; |
michael@0 | 284 | PRUint32 i; |
michael@0 | 285 | nssSession *session; |
michael@0 | 286 | NSSSlot *slot; |
michael@0 | 287 | CK_ULONG template_size; |
michael@0 | 288 | CK_ATTRIBUTE_PTR attr; |
michael@0 | 289 | CK_ATTRIBUTE cert_template[6]; |
michael@0 | 290 | /* Set up a template of all options chosen by caller */ |
michael@0 | 291 | NSS_CK_TEMPLATE_START(cert_template, attr, template_size); |
michael@0 | 292 | if (certTypeOpt) { |
michael@0 | 293 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE); |
michael@0 | 294 | } |
michael@0 | 295 | if (idOpt) { |
michael@0 | 296 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID); |
michael@0 | 297 | } |
michael@0 | 298 | if (encodingOpt) { |
michael@0 | 299 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); |
michael@0 | 300 | } |
michael@0 | 301 | if (issuerOpt) { |
michael@0 | 302 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER); |
michael@0 | 303 | } |
michael@0 | 304 | if (serialOpt) { |
michael@0 | 305 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER); |
michael@0 | 306 | } |
michael@0 | 307 | if (subjectOpt) { |
michael@0 | 308 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); |
michael@0 | 309 | } |
michael@0 | 310 | NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size); |
michael@0 | 311 | if (template_size == 0) { |
michael@0 | 312 | /* caller didn't want anything */ |
michael@0 | 313 | return PR_SUCCESS; |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt, |
michael@0 | 317 | certObject, CKO_CERTIFICATE, |
michael@0 | 318 | cert_template, template_size); |
michael@0 | 319 | if (status != PR_SUCCESS) { |
michael@0 | 320 | |
michael@0 | 321 | session = sessionOpt ? |
michael@0 | 322 | sessionOpt : |
michael@0 | 323 | nssToken_GetDefaultSession(certObject->token); |
michael@0 | 324 | if (!session) { |
michael@0 | 325 | nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
michael@0 | 326 | return PR_FAILURE; |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | slot = nssToken_GetSlot(certObject->token); |
michael@0 | 330 | status = nssCKObject_GetAttributes(certObject->handle, |
michael@0 | 331 | cert_template, template_size, |
michael@0 | 332 | arenaOpt, session, slot); |
michael@0 | 333 | nssSlot_Destroy(slot); |
michael@0 | 334 | if (status != PR_SUCCESS) { |
michael@0 | 335 | return status; |
michael@0 | 336 | } |
michael@0 | 337 | } |
michael@0 | 338 | |
michael@0 | 339 | i=0; |
michael@0 | 340 | if (certTypeOpt) { |
michael@0 | 341 | *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++; |
michael@0 | 342 | } |
michael@0 | 343 | if (idOpt) { |
michael@0 | 344 | NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++; |
michael@0 | 345 | } |
michael@0 | 346 | if (encodingOpt) { |
michael@0 | 347 | NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++; |
michael@0 | 348 | } |
michael@0 | 349 | if (issuerOpt) { |
michael@0 | 350 | NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++; |
michael@0 | 351 | } |
michael@0 | 352 | if (serialOpt) { |
michael@0 | 353 | NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++; |
michael@0 | 354 | } |
michael@0 | 355 | if (subjectOpt) { |
michael@0 | 356 | NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++; |
michael@0 | 357 | } |
michael@0 | 358 | return PR_SUCCESS; |
michael@0 | 359 | } |
michael@0 | 360 | |
michael@0 | 361 | static nssTrustLevel |
michael@0 | 362 | get_nss_trust ( |
michael@0 | 363 | CK_TRUST ckt |
michael@0 | 364 | ) |
michael@0 | 365 | { |
michael@0 | 366 | nssTrustLevel t; |
michael@0 | 367 | switch (ckt) { |
michael@0 | 368 | case CKT_NSS_NOT_TRUSTED: t = nssTrustLevel_NotTrusted; break; |
michael@0 | 369 | case CKT_NSS_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator; |
michael@0 | 370 | break; |
michael@0 | 371 | case CKT_NSS_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break; |
michael@0 | 372 | case CKT_NSS_TRUSTED: t = nssTrustLevel_Trusted; break; |
michael@0 | 373 | case CKT_NSS_MUST_VERIFY_TRUST: t = nssTrustLevel_MustVerify; break; |
michael@0 | 374 | case CKT_NSS_TRUST_UNKNOWN: |
michael@0 | 375 | default: |
michael@0 | 376 | t = nssTrustLevel_Unknown; break; |
michael@0 | 377 | } |
michael@0 | 378 | return t; |
michael@0 | 379 | } |
michael@0 | 380 | |
michael@0 | 381 | NSS_IMPLEMENT PRStatus |
michael@0 | 382 | nssCryptokiTrust_GetAttributes ( |
michael@0 | 383 | nssCryptokiObject *trustObject, |
michael@0 | 384 | nssSession *sessionOpt, |
michael@0 | 385 | NSSItem *sha1_hash, |
michael@0 | 386 | nssTrustLevel *serverAuth, |
michael@0 | 387 | nssTrustLevel *clientAuth, |
michael@0 | 388 | nssTrustLevel *codeSigning, |
michael@0 | 389 | nssTrustLevel *emailProtection, |
michael@0 | 390 | PRBool *stepUpApproved |
michael@0 | 391 | ) |
michael@0 | 392 | { |
michael@0 | 393 | PRStatus status; |
michael@0 | 394 | NSSSlot *slot; |
michael@0 | 395 | nssSession *session; |
michael@0 | 396 | CK_BBOOL isToken = PR_FALSE; |
michael@0 | 397 | CK_BBOOL stepUp = PR_FALSE; |
michael@0 | 398 | CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN; |
michael@0 | 399 | CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN; |
michael@0 | 400 | CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN; |
michael@0 | 401 | CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN; |
michael@0 | 402 | CK_ATTRIBUTE_PTR attr; |
michael@0 | 403 | CK_ATTRIBUTE trust_template[7]; |
michael@0 | 404 | CK_ATTRIBUTE_PTR sha1_hash_attr; |
michael@0 | 405 | CK_ULONG trust_size; |
michael@0 | 406 | |
michael@0 | 407 | /* Use the trust object to find the trust settings */ |
michael@0 | 408 | NSS_CK_TEMPLATE_START(trust_template, attr, trust_size); |
michael@0 | 409 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); |
michael@0 | 410 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust); |
michael@0 | 411 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust); |
michael@0 | 412 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust); |
michael@0 | 413 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); |
michael@0 | 414 | NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp); |
michael@0 | 415 | sha1_hash_attr = attr; |
michael@0 | 416 | NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash); |
michael@0 | 417 | NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); |
michael@0 | 418 | |
michael@0 | 419 | status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, |
michael@0 | 420 | trustObject, |
michael@0 | 421 | CKO_NSS_TRUST, |
michael@0 | 422 | trust_template, trust_size); |
michael@0 | 423 | if (status != PR_SUCCESS) { |
michael@0 | 424 | session = sessionOpt ? |
michael@0 | 425 | sessionOpt : |
michael@0 | 426 | nssToken_GetDefaultSession(trustObject->token); |
michael@0 | 427 | if (!session) { |
michael@0 | 428 | nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
michael@0 | 429 | return PR_FAILURE; |
michael@0 | 430 | } |
michael@0 | 431 | |
michael@0 | 432 | slot = nssToken_GetSlot(trustObject->token); |
michael@0 | 433 | status = nssCKObject_GetAttributes(trustObject->handle, |
michael@0 | 434 | trust_template, trust_size, |
michael@0 | 435 | NULL, session, slot); |
michael@0 | 436 | nssSlot_Destroy(slot); |
michael@0 | 437 | if (status != PR_SUCCESS) { |
michael@0 | 438 | return status; |
michael@0 | 439 | } |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | if (sha1_hash_attr->ulValueLen == -1) { |
michael@0 | 443 | /* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */ |
michael@0 | 444 | sha1_hash_attr->ulValueLen = 0; |
michael@0 | 445 | } |
michael@0 | 446 | sha1_hash->size = sha1_hash_attr->ulValueLen; |
michael@0 | 447 | *serverAuth = get_nss_trust(saTrust); |
michael@0 | 448 | *clientAuth = get_nss_trust(caTrust); |
michael@0 | 449 | *emailProtection = get_nss_trust(epTrust); |
michael@0 | 450 | *codeSigning = get_nss_trust(csTrust); |
michael@0 | 451 | *stepUpApproved = stepUp; |
michael@0 | 452 | return PR_SUCCESS; |
michael@0 | 453 | } |
michael@0 | 454 | |
michael@0 | 455 | NSS_IMPLEMENT PRStatus |
michael@0 | 456 | nssCryptokiCRL_GetAttributes ( |
michael@0 | 457 | nssCryptokiObject *crlObject, |
michael@0 | 458 | nssSession *sessionOpt, |
michael@0 | 459 | NSSArena *arenaOpt, |
michael@0 | 460 | NSSItem *encodingOpt, |
michael@0 | 461 | NSSItem *subjectOpt, |
michael@0 | 462 | CK_ULONG* crl_class, |
michael@0 | 463 | NSSUTF8 **urlOpt, |
michael@0 | 464 | PRBool *isKRLOpt |
michael@0 | 465 | ) |
michael@0 | 466 | { |
michael@0 | 467 | PRStatus status; |
michael@0 | 468 | NSSSlot *slot; |
michael@0 | 469 | nssSession *session; |
michael@0 | 470 | CK_ATTRIBUTE_PTR attr; |
michael@0 | 471 | CK_ATTRIBUTE crl_template[7]; |
michael@0 | 472 | CK_ULONG crl_size; |
michael@0 | 473 | PRUint32 i; |
michael@0 | 474 | |
michael@0 | 475 | NSS_CK_TEMPLATE_START(crl_template, attr, crl_size); |
michael@0 | 476 | if (crl_class) { |
michael@0 | 477 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS); |
michael@0 | 478 | } |
michael@0 | 479 | if (encodingOpt) { |
michael@0 | 480 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); |
michael@0 | 481 | } |
michael@0 | 482 | if (urlOpt) { |
michael@0 | 483 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL); |
michael@0 | 484 | } |
michael@0 | 485 | if (isKRLOpt) { |
michael@0 | 486 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL); |
michael@0 | 487 | } |
michael@0 | 488 | if (subjectOpt) { |
michael@0 | 489 | NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT); |
michael@0 | 490 | } |
michael@0 | 491 | NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size); |
michael@0 | 492 | |
michael@0 | 493 | status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL, |
michael@0 | 494 | crlObject, |
michael@0 | 495 | CKO_NSS_CRL, |
michael@0 | 496 | crl_template, crl_size); |
michael@0 | 497 | if (status != PR_SUCCESS) { |
michael@0 | 498 | session = sessionOpt ? |
michael@0 | 499 | sessionOpt : |
michael@0 | 500 | nssToken_GetDefaultSession(crlObject->token); |
michael@0 | 501 | if (session == NULL) { |
michael@0 | 502 | nss_SetError(NSS_ERROR_INVALID_ARGUMENT); |
michael@0 | 503 | return PR_FAILURE; |
michael@0 | 504 | } |
michael@0 | 505 | |
michael@0 | 506 | slot = nssToken_GetSlot(crlObject->token); |
michael@0 | 507 | status = nssCKObject_GetAttributes(crlObject->handle, |
michael@0 | 508 | crl_template, crl_size, |
michael@0 | 509 | arenaOpt, session, slot); |
michael@0 | 510 | nssSlot_Destroy(slot); |
michael@0 | 511 | if (status != PR_SUCCESS) { |
michael@0 | 512 | return status; |
michael@0 | 513 | } |
michael@0 | 514 | } |
michael@0 | 515 | |
michael@0 | 516 | i=0; |
michael@0 | 517 | if (crl_class) { |
michael@0 | 518 | NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++; |
michael@0 | 519 | } |
michael@0 | 520 | if (encodingOpt) { |
michael@0 | 521 | NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++; |
michael@0 | 522 | } |
michael@0 | 523 | if (urlOpt) { |
michael@0 | 524 | NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++; |
michael@0 | 525 | } |
michael@0 | 526 | if (isKRLOpt) { |
michael@0 | 527 | NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++; |
michael@0 | 528 | } |
michael@0 | 529 | if (subjectOpt) { |
michael@0 | 530 | NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++; |
michael@0 | 531 | } |
michael@0 | 532 | return PR_SUCCESS; |
michael@0 | 533 | } |
michael@0 | 534 | |
michael@0 | 535 | NSS_IMPLEMENT PRStatus |
michael@0 | 536 | nssCryptokiPrivateKey_SetCertificate ( |
michael@0 | 537 | nssCryptokiObject *keyObject, |
michael@0 | 538 | nssSession *sessionOpt, |
michael@0 | 539 | const NSSUTF8 *nickname, |
michael@0 | 540 | NSSItem *id, |
michael@0 | 541 | NSSDER *subject |
michael@0 | 542 | ) |
michael@0 | 543 | { |
michael@0 | 544 | CK_RV ckrv; |
michael@0 | 545 | CK_ATTRIBUTE_PTR attr; |
michael@0 | 546 | CK_ATTRIBUTE key_template[3]; |
michael@0 | 547 | CK_ULONG key_size; |
michael@0 | 548 | void *epv = nssToken_GetCryptokiEPV(keyObject->token); |
michael@0 | 549 | nssSession *session; |
michael@0 | 550 | NSSToken *token = keyObject->token; |
michael@0 | 551 | nssSession *defaultSession = nssToken_GetDefaultSession(token); |
michael@0 | 552 | PRBool createdSession = PR_FALSE; |
michael@0 | 553 | |
michael@0 | 554 | NSS_CK_TEMPLATE_START(key_template, attr, key_size); |
michael@0 | 555 | NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); |
michael@0 | 556 | NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); |
michael@0 | 557 | NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); |
michael@0 | 558 | NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size); |
michael@0 | 559 | |
michael@0 | 560 | if (sessionOpt) { |
michael@0 | 561 | if (!nssSession_IsReadWrite(sessionOpt)) { |
michael@0 | 562 | return PR_FAILURE; |
michael@0 | 563 | } |
michael@0 | 564 | session = sessionOpt; |
michael@0 | 565 | } else if (defaultSession && nssSession_IsReadWrite(defaultSession)) { |
michael@0 | 566 | session = defaultSession; |
michael@0 | 567 | } else { |
michael@0 | 568 | NSSSlot *slot = nssToken_GetSlot(token); |
michael@0 | 569 | session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE); |
michael@0 | 570 | nssSlot_Destroy(slot); |
michael@0 | 571 | if (!session) { |
michael@0 | 572 | return PR_FAILURE; |
michael@0 | 573 | } |
michael@0 | 574 | createdSession = PR_TRUE; |
michael@0 | 575 | } |
michael@0 | 576 | |
michael@0 | 577 | ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, |
michael@0 | 578 | keyObject->handle, |
michael@0 | 579 | key_template, |
michael@0 | 580 | key_size); |
michael@0 | 581 | |
michael@0 | 582 | if (createdSession) { |
michael@0 | 583 | nssSession_Destroy(session); |
michael@0 | 584 | } |
michael@0 | 585 | |
michael@0 | 586 | return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; |
michael@0 | 587 | } |
michael@0 | 588 |