| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 #include "nspr.h" | 4 #include "nspr.h" |
| 5 #include "secerr.h" | 5 #include "secerr.h" |
| 6 #include "secasn1.h" | 6 #include "secasn1.h" |
| 7 #include "seccomon.h" | 7 #include "seccomon.h" |
| 8 #include "pk11func.h" | 8 #include "pk11func.h" |
| 9 #include "certdb.h" | 9 #include "certdb.h" |
| 10 #include "certt.h" | 10 #include "certt.h" |
| 11 #include "cert.h" | 11 #include "cert.h" |
| 12 #include "certxutl.h" | 12 #include "certxutl.h" |
| 13 | 13 |
| 14 #include "nsspki.h" | 14 #include "nsspki.h" |
| 15 #include "pki.h" | 15 #include "pki.h" |
| 16 #include "pkit.h" | 16 #include "pkit.h" |
| 17 #include "pkitm.h" | 17 #include "pkitm.h" |
| 18 #include "pki3hack.h" | 18 #include "pki3hack.h" |
| 19 | 19 |
| 20 | |
| 21 PRBool | 20 PRBool |
| 22 CERT_MatchNickname(char *name1, char *name2) { | 21 CERT_MatchNickname(char *name1, char *name2) |
| 23 char *nickname1= NULL; | 22 { |
| 23 char *nickname1 = NULL; |
| 24 char *nickname2 = NULL; | 24 char *nickname2 = NULL; |
| 25 char *token1; | 25 char *token1; |
| 26 char *token2; | 26 char *token2; |
| 27 | 27 |
| 28 /* first deal with the straight comparison */ | 28 /* first deal with the straight comparison */ |
| 29 if (PORT_Strcmp(name1, name2) == 0) { | 29 if (PORT_Strcmp(name1, name2) == 0) { |
| 30 » return PR_TRUE; | 30 return PR_TRUE; |
| 31 } | 31 } |
| 32 /* we need to handle the case where one name has an explicit token and the o
ther | 32 /* we need to handle the case where one name has an explicit token and the o
ther |
| 33 * doesn't */ | 33 * doesn't */ |
| 34 token1 = PORT_Strchr(name1,':'); | 34 token1 = PORT_Strchr(name1, ':'); |
| 35 token2 = PORT_Strchr(name2,':'); | 35 token2 = PORT_Strchr(name2, ':'); |
| 36 if ((token1 && token2) || (!token1 && !token2)) { | 36 if ((token1 && token2) || (!token1 && !token2)) { |
| 37 » /* either both token names are specified or neither are, not match */ | 37 /* either both token names are specified or neither are, not match */ |
| 38 » return PR_FALSE; | 38 return PR_FALSE; |
| 39 } | 39 } |
| 40 if (token1) { | 40 if (token1) { |
| 41 » nickname1=token1; | 41 nickname1 = token1; |
| 42 » nickname2=name2; | 42 nickname2 = name2; |
| 43 } else { | 43 } else { |
| 44 » nickname1=token2; | 44 nickname1 = token2; |
| 45 » nickname2=name1; | 45 nickname2 = name1; |
| 46 } | 46 } |
| 47 nickname1++; | 47 nickname1++; |
| 48 if (PORT_Strcmp(nickname1,nickname2) != 0) { | 48 if (PORT_Strcmp(nickname1, nickname2) != 0) { |
| 49 » return PR_FALSE; | 49 return PR_FALSE; |
| 50 } | 50 } |
| 51 /* Bug 1192443 - compare the other token with the internal slot here */ | 51 /* Bug 1192443 - compare the other token with the internal slot here */ |
| 52 return PR_TRUE; | 52 return PR_TRUE; |
| 53 } | 53 } |
| 54 | 54 |
| 55 /* | 55 /* |
| 56 * Find all user certificates that match the given criteria. | 56 * Find all user certificates that match the given criteria. |
| 57 * | 57 * |
| 58 * "handle" - database to search | 58 * "handle" - database to search |
| 59 * "usage" - certificate usage to match | 59 * "usage" - certificate usage to match |
| 60 * "oneCertPerName" - if set then only return the "best" cert per | 60 * "oneCertPerName" - if set then only return the "best" cert per |
| 61 * name | 61 * name |
| 62 * "validOnly" - only return certs that are curently valid | 62 * "validOnly" - only return certs that are curently valid |
| 63 * "proto_win" - window handle passed to pkcs11 | 63 * "proto_win" - window handle passed to pkcs11 |
| 64 */ | 64 */ |
| 65 CERTCertList * | 65 CERTCertList * |
| 66 CERT_FindUserCertsByUsage(CERTCertDBHandle *handle, | 66 CERT_FindUserCertsByUsage(CERTCertDBHandle *handle, |
| 67 » » » SECCertUsage usage, | 67 SECCertUsage usage, |
| 68 » » » PRBool oneCertPerName, | 68 PRBool oneCertPerName, |
| 69 » » » PRBool validOnly, | 69 PRBool validOnly, |
| 70 » » » void *proto_win) | 70 void *proto_win) |
| 71 { | 71 { |
| 72 CERTCertNicknames *nicknames = NULL; | 72 CERTCertNicknames *nicknames = NULL; |
| 73 char **nnptr; | 73 char **nnptr; |
| 74 int nn; | 74 int nn; |
| 75 CERTCertificate *cert = NULL; | 75 CERTCertificate *cert = NULL; |
| 76 CERTCertList *certList = NULL; | 76 CERTCertList *certList = NULL; |
| 77 SECStatus rv; | 77 SECStatus rv; |
| 78 PRTime time; | 78 PRTime time; |
| 79 CERTCertListNode *node = NULL; | 79 CERTCertListNode *node = NULL; |
| 80 CERTCertListNode *freenode = NULL; | 80 CERTCertListNode *freenode = NULL; |
| 81 int n; | 81 int n; |
| 82 | 82 |
| 83 time = PR_Now(); | 83 time = PR_Now(); |
| 84 | 84 |
| 85 nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER, | 85 nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER, |
| 86 » » » » proto_win); | 86 proto_win); |
| 87 | 87 |
| 88 if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) { | 88 if ((nicknames == NULL) || (nicknames->numnicknames == 0)) { |
| 89 » goto loser; | 89 goto loser; |
| 90 } | 90 } |
| 91 | 91 |
| 92 nnptr = nicknames->nicknames; | 92 nnptr = nicknames->nicknames; |
| 93 nn = nicknames->numnicknames; | 93 nn = nicknames->numnicknames; |
| 94 | 94 |
| 95 while ( nn > 0 ) { | 95 while (nn > 0) { |
| 96 » cert = NULL; | 96 cert = NULL; |
| 97 » /* use the pk11 call so that we pick up any certs on tokens, | 97 /* use the pk11 call so that we pick up any certs on tokens, |
| 98 * which may require login | 98 * which may require login |
| 99 */ | 99 */ |
| 100 » if ( proto_win != NULL ) { | 100 if (proto_win != NULL) { |
| 101 » cert = PK11_FindCertFromNickname(*nnptr,proto_win); | 101 cert = PK11_FindCertFromNickname(*nnptr, proto_win); |
| 102 » } | 102 } |
| 103 | 103 |
| 104 » /* Sigh, It turns out if the cert is already in the temp db, because | 104 /* Sigh, It turns out if the cert is already in the temp db, because |
| 105 * it's in the perm db, then the nickname lookup doesn't work. | 105 * it's in the perm db, then the nickname lookup doesn't work. |
| 106 * since we already have the cert here, though, than we can just call | 106 * since we already have the cert here, though, than we can just call |
| 107 * CERT_CreateSubjectCertList directly. For those cases where we didn't | 107 * CERT_CreateSubjectCertList directly. For those cases where we didn't |
| 108 * find the cert in pkcs #11 (because we didn't have a password arg, | 108 * find the cert in pkcs #11 (because we didn't have a password arg, |
| 109 * or because the nickname is for a peer, server, or CA cert, then we | 109 * or because the nickname is for a peer, server, or CA cert, then we |
| 110 * go look the cert up. | 110 * go look the cert up. |
| 111 */ | 111 */ |
| 112 » if (cert == NULL) { | 112 if (cert == NULL) { |
| 113 » cert = CERT_FindCertByNickname(handle,*nnptr); | 113 cert = CERT_FindCertByNickname(handle, *nnptr); |
| 114 » } | 114 } |
| 115 | 115 |
| 116 » if ( cert != NULL ) { | 116 if (cert != NULL) { |
| 117 » /* collect certs for this nickname, sorting them into the list */ | 117 /* collect certs for this nickname, sorting them into the list */ |
| 118 » certList = CERT_CreateSubjectCertList(certList, handle, | 118 certList = CERT_CreateSubjectCertList(certList, handle, |
| 119 » » » » &cert->derSubject, time, validOnly); | 119 &cert->derSubject, time, valid
Only); |
| 120 | 120 |
| 121 » CERT_FilterCertListForUserCerts(certList); | 121 CERT_FilterCertListForUserCerts(certList); |
| 122 » | 122 |
| 123 » /* drop the extra reference */ | 123 /* drop the extra reference */ |
| 124 » CERT_DestroyCertificate(cert); | 124 CERT_DestroyCertificate(cert); |
| 125 » } | 125 } |
| 126 » | 126 |
| 127 » nnptr++; | 127 nnptr++; |
| 128 » nn--; | 128 nn--; |
| 129 } | 129 } |
| 130 | 130 |
| 131 /* remove certs with incorrect usage */ | 131 /* remove certs with incorrect usage */ |
| 132 rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); | 132 rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); |
| 133 | 133 |
| 134 if ( rv != SECSuccess ) { | 134 if (rv != SECSuccess) { |
| 135 » goto loser; | 135 goto loser; |
| 136 } | 136 } |
| 137 | 137 |
| 138 /* remove any extra certs for each name */ | 138 /* remove any extra certs for each name */ |
| 139 if ( oneCertPerName ) { | 139 if (oneCertPerName) { |
| 140 » PRBool *flags; | 140 PRBool *flags; |
| 141 | 141 |
| 142 » nn = nicknames->numnicknames; | 142 nn = nicknames->numnicknames; |
| 143 » nnptr = nicknames->nicknames; | 143 nnptr = nicknames->nicknames; |
| 144 » | |
| 145 » flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn); | |
| 146 » if ( flags == NULL ) { | |
| 147 » goto loser; | |
| 148 » } | |
| 149 » | |
| 150 » node = CERT_LIST_HEAD(certList); | |
| 151 » | |
| 152 » /* treverse all certs in the list */ | |
| 153 » while ( !CERT_LIST_END(node, certList) ) { | |
| 154 | 144 |
| 155 » /* find matching nickname index */ | 145 flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn); |
| 156 » for ( n = 0; n < nn; n++ ) { | 146 if (flags == NULL) { |
| 157 » » if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) { | 147 goto loser; |
| 158 » » /* We found a match. If this is the first one, then | 148 } |
| 149 |
| 150 node = CERT_LIST_HEAD(certList); |
| 151 |
| 152 /* treverse all certs in the list */ |
| 153 while (!CERT_LIST_END(node, certList)) { |
| 154 |
| 155 /* find matching nickname index */ |
| 156 for (n = 0; n < nn; n++) { |
| 157 if (CERT_MatchNickname(nnptr[n], node->cert->nickname)) { |
| 158 /* We found a match. If this is the first one, then |
| 159 * set the flag and move on to the next cert. If this | 159 * set the flag and move on to the next cert. If this |
| 160 * is not the first one then delete it from the list. | 160 * is not the first one then delete it from the list. |
| 161 */ | 161 */ |
| 162 » » if ( flags[n] ) { | 162 if (flags[n]) { |
| 163 » » » /* We have already seen a cert with this nickname, | 163 /* We have already seen a cert with this nickname, |
| 164 * so delete this one. | 164 * so delete this one. |
| 165 */ | 165 */ |
| 166 » » » freenode = node; | 166 freenode = node; |
| 167 » » » node = CERT_LIST_NEXT(node); | 167 node = CERT_LIST_NEXT(node); |
| 168 » » » CERT_RemoveCertListNode(freenode); | 168 CERT_RemoveCertListNode(freenode); |
| 169 » » } else { | 169 } else { |
| 170 » » » /* keep the first cert for each nickname, but set the | 170 /* keep the first cert for each nickname, but set the |
| 171 * flag so we know to delete any others with the same | 171 * flag so we know to delete any others with the same |
| 172 * nickname. | 172 * nickname. |
| 173 */ | 173 */ |
| 174 » » » flags[n] = PR_TRUE; | 174 flags[n] = PR_TRUE; |
| 175 » » » node = CERT_LIST_NEXT(node); | 175 node = CERT_LIST_NEXT(node); |
| 176 » » } | 176 } |
| 177 » » break; | 177 break; |
| 178 » » } | 178 } |
| 179 » } | 179 } |
| 180 » if ( n == nn ) { | 180 if (n == nn) { |
| 181 » » /* if we get here it means that we didn't find a matching | 181 /* if we get here it means that we didn't find a matching |
| 182 * nickname, which should not happen. | 182 * nickname, which should not happen. |
| 183 */ | 183 */ |
| 184 » » PORT_Assert(0); | 184 PORT_Assert(0); |
| 185 » » node = CERT_LIST_NEXT(node); | 185 node = CERT_LIST_NEXT(node); |
| 186 » } | 186 } |
| 187 » } | 187 } |
| 188 » PORT_Free(flags); | 188 PORT_Free(flags); |
| 189 } | 189 } |
| 190 | 190 |
| 191 goto done; | 191 goto done; |
| 192 | 192 |
| 193 loser: | 193 loser: |
| 194 if ( certList != NULL ) { | 194 if (certList != NULL) { |
| 195 » CERT_DestroyCertList(certList); | 195 CERT_DestroyCertList(certList); |
| 196 » certList = NULL; | 196 certList = NULL; |
| 197 } | 197 } |
| 198 | 198 |
| 199 done: | 199 done: |
| 200 if ( nicknames != NULL ) { | 200 if (nicknames != NULL) { |
| 201 » CERT_FreeNicknames(nicknames); | 201 CERT_FreeNicknames(nicknames); |
| 202 } | 202 } |
| 203 | 203 |
| 204 return(certList); | 204 return (certList); |
| 205 } | 205 } |
| 206 | 206 |
| 207 /* | 207 /* |
| 208 * Find a user certificate that matchs the given criteria. | 208 * Find a user certificate that matchs the given criteria. |
| 209 * | 209 * |
| 210 * "handle" - database to search | 210 * "handle" - database to search |
| 211 * "nickname" - nickname to match | 211 * "nickname" - nickname to match |
| 212 * "usage" - certificate usage to match | 212 * "usage" - certificate usage to match |
| 213 * "validOnly" - only return certs that are curently valid | 213 * "validOnly" - only return certs that are curently valid |
| 214 * "proto_win" - window handle passed to pkcs11 | 214 * "proto_win" - window handle passed to pkcs11 |
| 215 */ | 215 */ |
| 216 CERTCertificate * | 216 CERTCertificate * |
| 217 CERT_FindUserCertByUsage(CERTCertDBHandle *handle, | 217 CERT_FindUserCertByUsage(CERTCertDBHandle *handle, |
| 218 » » » const char *nickname, | 218 const char *nickname, |
| 219 » » » SECCertUsage usage, | 219 SECCertUsage usage, |
| 220 » » » PRBool validOnly, | 220 PRBool validOnly, |
| 221 » » » void *proto_win) | 221 void *proto_win) |
| 222 { | 222 { |
| 223 CERTCertificate *cert = NULL; | 223 CERTCertificate *cert = NULL; |
| 224 CERTCertList *certList = NULL; | 224 CERTCertList *certList = NULL; |
| 225 SECStatus rv; | 225 SECStatus rv; |
| 226 PRTime time; | 226 PRTime time; |
| 227 | 227 |
| 228 time = PR_Now(); | 228 time = PR_Now(); |
| 229 | 229 |
| 230 /* use the pk11 call so that we pick up any certs on tokens, | 230 /* use the pk11 call so that we pick up any certs on tokens, |
| 231 * which may require login | 231 * which may require login |
| 232 */ | 232 */ |
| 233 /* XXX - why is this restricted? */ | 233 /* XXX - why is this restricted? */ |
| 234 if ( proto_win != NULL ) { | 234 if (proto_win != NULL) { |
| 235 » cert = PK11_FindCertFromNickname(nickname,proto_win); | 235 cert = PK11_FindCertFromNickname(nickname, proto_win); |
| 236 } | 236 } |
| 237 | 237 |
| 238 | |
| 239 /* sigh, There are still problems find smart cards from the temp | 238 /* sigh, There are still problems find smart cards from the temp |
| 240 * db. This will get smart cards working again. The real fix | 239 * db. This will get smart cards working again. The real fix |
| 241 * is to make sure we can search the temp db by their token nickname. | 240 * is to make sure we can search the temp db by their token nickname. |
| 242 */ | 241 */ |
| 243 if (cert == NULL) { | 242 if (cert == NULL) { |
| 244 » cert = CERT_FindCertByNickname(handle,nickname); | 243 cert = CERT_FindCertByNickname(handle, nickname); |
| 245 } | 244 } |
| 246 | 245 |
| 247 if ( cert != NULL ) { | 246 if (cert != NULL) { |
| 248 » unsigned int requiredKeyUsage; | 247 unsigned int requiredKeyUsage; |
| 249 » unsigned int requiredCertType; | 248 unsigned int requiredCertType; |
| 250 | 249 |
| 251 » rv = CERT_KeyUsageAndTypeForCertUsage(usage, PR_FALSE, | 250 rv = CERT_KeyUsageAndTypeForCertUsage(usage, PR_FALSE, |
| 252 » » » » » &requiredKeyUsage, &requiredCertType); | 251 &requiredKeyUsage, &requiredCertTy
pe); |
| 253 » if ( rv != SECSuccess ) { | 252 if (rv != SECSuccess) { |
| 254 » /* drop the extra reference */ | 253 /* drop the extra reference */ |
| 255 » CERT_DestroyCertificate(cert); | 254 CERT_DestroyCertificate(cert); |
| 256 » cert = NULL; | 255 cert = NULL; |
| 257 » goto loser; | 256 goto loser; |
| 258 » } | 257 } |
| 259 » /* If we already found the right cert, just return it */ | 258 /* If we already found the right cert, just return it */ |
| 260 » if ( (!validOnly || CERT_CheckCertValidTimes(cert, time, PR_FALSE) | 259 if ((!validOnly || CERT_CheckCertValidTimes(cert, time, PR_FALSE) == |
| 261 » == secCertTimeValid) && | 260 secCertTimeValid) && |
| 262 » (CERT_CheckKeyUsage(cert, requiredKeyUsage) == SECSuccess) && | 261 (CERT_CheckKeyUsage(cert, requiredKeyUsage) == SECSuccess) && |
| 263 » (cert->nsCertType & requiredCertType) && | 262 (cert->nsCertType & requiredCertType) && |
| 264 » CERT_IsUserCert(cert) ) { | 263 CERT_IsUserCert(cert)) { |
| 265 » return(cert); | 264 return (cert); |
| 266 » } | 265 } |
| 267 | 266 |
| 268 » /* collect certs for this nickname, sorting them into the list */ | 267 /* collect certs for this nickname, sorting them into the list */ |
| 269 » certList = CERT_CreateSubjectCertList(certList, handle, | 268 certList = CERT_CreateSubjectCertList(certList, handle, |
| 270 » » » » » &cert->derSubject, time, validOnly); | 269 &cert->derSubject, time, validOnly
); |
| 271 | 270 |
| 272 » CERT_FilterCertListForUserCerts(certList); | 271 CERT_FilterCertListForUserCerts(certList); |
| 273 | 272 |
| 274 » /* drop the extra reference */ | 273 /* drop the extra reference */ |
| 275 » CERT_DestroyCertificate(cert); | 274 CERT_DestroyCertificate(cert); |
| 276 » cert = NULL; | 275 cert = NULL; |
| 277 } | 276 } |
| 278 » | 277 |
| 279 if ( certList == NULL ) { | 278 if (certList == NULL) { |
| 280 » goto loser; | 279 goto loser; |
| 281 } | 280 } |
| 282 | 281 |
| 283 /* remove certs with incorrect usage */ | 282 /* remove certs with incorrect usage */ |
| 284 rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); | 283 rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); |
| 285 | 284 |
| 286 if ( rv != SECSuccess ) { | 285 if (rv != SECSuccess) { |
| 287 » goto loser; | 286 goto loser; |
| 288 } | 287 } |
| 289 | 288 |
| 290 if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) { | 289 if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) { |
| 291 » cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert); | 290 cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert); |
| 292 } | |
| 293 | |
| 294 loser: | |
| 295 if ( certList != NULL ) { | |
| 296 » CERT_DestroyCertList(certList); | |
| 297 } | 291 } |
| 298 | 292 |
| 299 return(cert); | 293 loser: |
| 294 if (certList != NULL) { |
| 295 CERT_DestroyCertList(certList); |
| 296 } |
| 297 |
| 298 return (cert); |
| 300 } | 299 } |
| 301 | 300 |
| 302 CERTCertList * | 301 CERTCertList * |
| 303 CERT_MatchUserCert(CERTCertDBHandle *handle, | 302 CERT_MatchUserCert(CERTCertDBHandle *handle, |
| 304 » » SECCertUsage usage, | 303 SECCertUsage usage, |
| 305 » » int nCANames, char **caNames, | 304 int nCANames, char **caNames, |
| 306 » » void *proto_win) | 305 void *proto_win) |
| 307 { | 306 { |
| 308 CERTCertList *certList = NULL; | 307 CERTCertList *certList = NULL; |
| 309 SECStatus rv; | 308 SECStatus rv; |
| 310 | 309 |
| 311 certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE, | 310 certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE, |
| 312 » » » » » proto_win); | 311 proto_win); |
| 313 if ( certList == NULL ) { | 312 if (certList == NULL) { |
| 314 » goto loser; | 313 goto loser; |
| 315 } | 314 } |
| 316 | 315 |
| 317 rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage); | 316 rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage); |
| 318 if ( rv != SECSuccess ) { | 317 if (rv != SECSuccess) { |
| 319 » goto loser; | 318 goto loser; |
| 320 } | 319 } |
| 321 | 320 |
| 322 goto done; | 321 goto done; |
| 323 | 322 |
| 324 loser: | 323 loser: |
| 325 if ( certList != NULL ) { | 324 if (certList != NULL) { |
| 326 » CERT_DestroyCertList(certList); | 325 CERT_DestroyCertList(certList); |
| 327 » certList = NULL; | 326 certList = NULL; |
| 328 } | 327 } |
| 329 | 328 |
| 330 done: | 329 done: |
| 331 | 330 |
| 332 return(certList); | 331 return (certList); |
| 333 } | 332 } |
| 334 | 333 |
| 335 | |
| 336 typedef struct stringNode { | 334 typedef struct stringNode { |
| 337 struct stringNode *next; | 335 struct stringNode *next; |
| 338 char *string; | 336 char *string; |
| 339 } stringNode; | 337 } stringNode; |
| 340 | 338 |
| 341 static PRStatus | 339 static PRStatus |
| 342 CollectNicknames( NSSCertificate *c, void *data) | 340 CollectNicknames(NSSCertificate *c, void *data) |
| 343 { | 341 { |
| 344 CERTCertNicknames *names; | 342 CERTCertNicknames *names; |
| 345 PRBool saveit = PR_FALSE; | 343 PRBool saveit = PR_FALSE; |
| 346 stringNode *node; | 344 stringNode *node; |
| 347 int len; | 345 int len; |
| 348 #ifdef notdef | 346 #ifdef notdef |
| 349 NSSTrustDomain *td; | 347 NSSTrustDomain *td; |
| 350 NSSTrust *trust; | 348 NSSTrust *trust; |
| 351 #endif | 349 #endif |
| 352 char *stanNickname; | 350 char *stanNickname; |
| 353 char *nickname = NULL; | 351 char *nickname = NULL; |
| 354 | 352 |
| 355 names = (CERTCertNicknames *)data; | 353 names = (CERTCertNicknames *)data; |
| 356 | 354 |
| 357 stanNickname = nssCertificate_GetNickname(c,NULL); | 355 stanNickname = nssCertificate_GetNickname(c, NULL); |
| 358 | 356 |
| 359 if ( stanNickname ) { | 357 if (stanNickname) { |
| 360 nss_ZFreeIf(stanNickname); | 358 nss_ZFreeIf(stanNickname); |
| 361 stanNickname = NULL; | 359 stanNickname = NULL; |
| 362 » if (names->what == SEC_CERT_NICKNAMES_USER) { | 360 if (names->what == SEC_CERT_NICKNAMES_USER) { |
| 363 » saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL); | 361 saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL); |
| 364 » } | 362 } |
| 365 #ifdef notdef | 363 #ifdef notdef |
| 366 » else { | 364 else { |
| 367 » td = NSSCertificate_GetTrustDomain(c); | 365 td = NSSCertificate_GetTrustDomain(c); |
| 368 » if (!td) { | 366 if (!td) { |
| 369 » » return PR_SUCCESS; | 367 return PR_SUCCESS; |
| 370 » } | 368 } |
| 371 » trust = nssTrustDomain_FindTrustForCertificate(td,c); | 369 trust = nssTrustDomain_FindTrustForCertificate(td, c); |
| 372 » | 370 |
| 373 » switch(names->what) { | 371 switch (names->what) { |
| 374 » case SEC_CERT_NICKNAMES_ALL: | 372 case SEC_CERT_NICKNAMES_ALL: |
| 375 » » if ((trust->sslFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) || | 373 if ((trust->sslFlags & (CERTDB_VALID_CA | CERTDB_VALID_PEER)
) || |
| 376 » » (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) || | 374 (trust->emailFlags & (CERTDB_VALID_CA | CERTDB_VALID_PEE
R)) || |
| 377 » » (trust->objectSigningFlags & | 375 (trust->objectSigningFlags & |
| 378 » » » » » (CERTDB_VALID_CA|CERTDB_VALID_PEER))) { | 376 (CERTDB_VALID_CA | CERTDB_VALID_PEER))) { |
| 379 » » saveit = PR_TRUE; | 377 saveit = PR_TRUE; |
| 380 » » } | 378 } |
| 381 » | 379 |
| 382 » » break; | 380 break; |
| 383 » case SEC_CERT_NICKNAMES_SERVER: | 381 case SEC_CERT_NICKNAMES_SERVER: |
| 384 » » if ( trust->sslFlags & CERTDB_VALID_PEER ) { | 382 if (trust->sslFlags & CERTDB_VALID_PEER) { |
| 385 » » saveit = PR_TRUE; | 383 saveit = PR_TRUE; |
| 386 » » } | 384 } |
| 387 » | 385 |
| 388 » » break; | 386 break; |
| 389 » case SEC_CERT_NICKNAMES_CA: | 387 case SEC_CERT_NICKNAMES_CA: |
| 390 » » if (((trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA)|| | 388 if (((trust->sslFlags & CERTDB_VALID_CA) == CERTDB_VALID_CA)
|| |
| 391 » » ((trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA) || | 389 ((trust->emailFlags & CERTDB_VALID_CA) == CERTDB_VALID_C
A) || |
| 392 » » ((trust->objectSigningFlags & CERTDB_VALID_CA ) | 390 ((trust->objectSigningFlags & CERTDB_VALID_CA) == |
| 393 » » » » » » » == CERTDB_VALID_CA)) { | 391 CERTDB_VALID_CA)) { |
| 394 » » saveit = PR_TRUE; | 392 saveit = PR_TRUE; |
| 395 » » } | 393 } |
| 396 » » break; | 394 break; |
| 397 » } | 395 } |
| 398 » } | 396 } |
| 399 #endif | 397 #endif |
| 400 } | 398 } |
| 401 | 399 |
| 402 /* traverse the list of collected nicknames and make sure we don't make | 400 /* traverse the list of collected nicknames and make sure we don't make |
| 403 * a duplicate | 401 * a duplicate |
| 404 */ | 402 */ |
| 405 if ( saveit ) { | 403 if (saveit) { |
| 406 » nickname = STAN_GetCERTCertificateName(NULL, c); | 404 nickname = STAN_GetCERTCertificateName(NULL, c); |
| 407 » /* nickname can only be NULL here if we are having memory | 405 /* nickname can only be NULL here if we are having memory |
| 408 * alloc problems */ | 406 * alloc problems */ |
| 409 » if (nickname == NULL) { | 407 if (nickname == NULL) { |
| 410 » return PR_FAILURE; | 408 return PR_FAILURE; |
| 411 » } | 409 } |
| 412 » node = (stringNode *)names->head; | 410 node = (stringNode *)names->head; |
| 413 » while ( node != NULL ) { | 411 while (node != NULL) { |
| 414 » if ( PORT_Strcmp(nickname, node->string) == 0 ) { | 412 if (PORT_Strcmp(nickname, node->string) == 0) { |
| 415 » » /* if the string matches, then don't save this one */ | 413 /* if the string matches, then don't save this one */ |
| 416 » » saveit = PR_FALSE; | 414 saveit = PR_FALSE; |
| 417 » » break; | 415 break; |
| 418 » } | 416 } |
| 419 » node = node->next; | 417 node = node->next; |
| 420 » } | 418 } |
| 421 } | 419 } |
| 422 | 420 |
| 423 if ( saveit ) { | 421 if (saveit) { |
| 424 » | |
| 425 » /* allocate the node */ | |
| 426 » node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode)); | |
| 427 » if ( node == NULL ) { | |
| 428 » PORT_Free(nickname); | |
| 429 » return PR_FAILURE; | |
| 430 » } | |
| 431 | 422 |
| 432 » /* copy the string */ | 423 /* allocate the node */ |
| 433 » len = PORT_Strlen(nickname) + 1; | 424 node = (stringNode *)PORT_ArenaAlloc(names->arena, sizeof(stringNode)); |
| 434 » node->string = (char*)PORT_ArenaAlloc(names->arena, len); | 425 if (node == NULL) { |
| 435 » if ( node->string == NULL ) { | 426 PORT_Free(nickname); |
| 436 » PORT_Free(nickname); | 427 return PR_FAILURE; |
| 437 » return PR_FAILURE; | 428 } |
| 438 » } | |
| 439 » PORT_Memcpy(node->string, nickname, len); | |
| 440 | 429 |
| 441 » /* link it into the list */ | 430 /* copy the string */ |
| 442 » node->next = (stringNode *)names->head; | 431 len = PORT_Strlen(nickname) + 1; |
| 443 » names->head = (void *)node; | 432 node->string = (char *)PORT_ArenaAlloc(names->arena, len); |
| 433 if (node->string == NULL) { |
| 434 PORT_Free(nickname); |
| 435 return PR_FAILURE; |
| 436 } |
| 437 PORT_Memcpy(node->string, nickname, len); |
| 444 | 438 |
| 445 » /* bump the count */ | 439 /* link it into the list */ |
| 446 » names->numnicknames++; | 440 node->next = (stringNode *)names->head; |
| 441 names->head = (void *)node; |
| 442 |
| 443 /* bump the count */ |
| 444 names->numnicknames++; |
| 447 } | 445 } |
| 448 | 446 |
| 449 if (nickname) PORT_Free(nickname); | 447 if (nickname) |
| 450 return(PR_SUCCESS); | 448 PORT_Free(nickname); |
| 449 return (PR_SUCCESS); |
| 451 } | 450 } |
| 452 | 451 |
| 453 CERTCertNicknames * | 452 CERTCertNicknames * |
| 454 CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) | 453 CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) |
| 455 { | 454 { |
| 456 PLArenaPool *arena; | 455 PLArenaPool *arena; |
| 457 CERTCertNicknames *names; | 456 CERTCertNicknames *names; |
| 458 int i; | 457 int i; |
| 459 stringNode *node; | 458 stringNode *node; |
| 460 | 459 |
| 461 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 460 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 462 if ( arena == NULL ) { | 461 if (arena == NULL) { |
| 463 » PORT_SetError(SEC_ERROR_NO_MEMORY); | 462 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 464 » return(NULL); | 463 return (NULL); |
| 465 } | 464 } |
| 466 | 465 |
| 467 names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames
)); | 466 names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames
)); |
| 468 if ( names == NULL ) { | 467 if (names == NULL) { |
| 469 » goto loser; | 468 goto loser; |
| 470 } | 469 } |
| 471 | 470 |
| 472 names->arena = arena; | 471 names->arena = arena; |
| 473 names->head = NULL; | 472 names->head = NULL; |
| 474 names->numnicknames = 0; | 473 names->numnicknames = 0; |
| 475 names->nicknames = NULL; | 474 names->nicknames = NULL; |
| 476 names->what = what; | 475 names->what = what; |
| 477 names->totallen = 0; | 476 names->totallen = 0; |
| 478 | 477 |
| 479 /* make sure we are logged in */ | 478 /* make sure we are logged in */ |
| 480 (void) pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx); | 479 (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx); |
| 481 | 480 |
| 482 NSSTrustDomain_TraverseCertificates(handle, | 481 NSSTrustDomain_TraverseCertificates(handle, |
| 483 » » » » » CollectNicknames, (void *)names); | 482 CollectNicknames, (void *)names); |
| 484 if ( names->numnicknames ) { | 483 if (names->numnicknames) { |
| 485 » names->nicknames = (char**)PORT_ArenaAlloc(arena, | 484 names->nicknames = (char **)PORT_ArenaAlloc(arena, |
| 486 » » » » » names->numnicknames * sizeof(char *)); | 485 names->numnicknames * |
| 486 sizeof(char *)); |
| 487 | 487 |
| 488 » if ( names->nicknames == NULL ) { | 488 if (names->nicknames == NULL) { |
| 489 » goto loser; | 489 goto loser; |
| 490 » } | 490 } |
| 491 | |
| 492 » node = (stringNode *)names->head; | |
| 493 » | |
| 494 » for ( i = 0; i < names->numnicknames; i++ ) { | |
| 495 » PORT_Assert(node != NULL); | |
| 496 » | |
| 497 » names->nicknames[i] = node->string; | |
| 498 » names->totallen += PORT_Strlen(node->string); | |
| 499 » node = node->next; | |
| 500 » } | |
| 501 | 491 |
| 502 » PORT_Assert(node == NULL); | 492 node = (stringNode *)names->head; |
| 493 |
| 494 for (i = 0; i < names->numnicknames; i++) { |
| 495 PORT_Assert(node != NULL); |
| 496 |
| 497 names->nicknames[i] = node->string; |
| 498 names->totallen += PORT_Strlen(node->string); |
| 499 node = node->next; |
| 500 } |
| 501 |
| 502 PORT_Assert(node == NULL); |
| 503 } | 503 } |
| 504 | 504 |
| 505 return(names); | 505 return (names); |
| 506 | 506 |
| 507 loser: | 507 loser: |
| 508 PORT_FreeArena(arena, PR_FALSE); | 508 PORT_FreeArena(arena, PR_FALSE); |
| 509 return(NULL); | 509 return (NULL); |
| 510 } | 510 } |
| 511 | 511 |
| 512 void | 512 void |
| 513 CERT_FreeNicknames(CERTCertNicknames *nicknames) | 513 CERT_FreeNicknames(CERTCertNicknames *nicknames) |
| 514 { | 514 { |
| 515 PORT_FreeArena(nicknames->arena, PR_FALSE); | 515 PORT_FreeArena(nicknames->arena, PR_FALSE); |
| 516 | 516 |
| 517 return; | 517 return; |
| 518 } | 518 } |
| 519 | 519 |
| 520 /* [ FROM pcertdb.c ] */ | 520 /* [ FROM pcertdb.c ] */ |
| 521 | 521 |
| 522 typedef struct dnameNode { | 522 typedef struct dnameNode { |
| 523 struct dnameNode *next; | 523 struct dnameNode *next; |
| 524 SECItem name; | 524 SECItem name; |
| 525 } dnameNode; | 525 } dnameNode; |
| 526 | 526 |
| 527 void | 527 void |
| 528 CERT_FreeDistNames(CERTDistNames *names) | 528 CERT_FreeDistNames(CERTDistNames *names) |
| 529 { | 529 { |
| 530 PORT_FreeArena(names->arena, PR_FALSE); | 530 PORT_FreeArena(names->arena, PR_FALSE); |
| 531 | 531 |
| 532 return; | 532 return; |
| 533 } | 533 } |
| 534 | 534 |
| 535 static SECStatus | 535 static SECStatus |
| 536 CollectDistNames( CERTCertificate *cert, SECItem *k, void *data) | 536 CollectDistNames(CERTCertificate *cert, SECItem *k, void *data) |
| 537 { | 537 { |
| 538 CERTDistNames *names; | 538 CERTDistNames *names; |
| 539 PRBool saveit = PR_FALSE; | 539 PRBool saveit = PR_FALSE; |
| 540 CERTCertTrust trust; | 540 CERTCertTrust trust; |
| 541 dnameNode *node; | 541 dnameNode *node; |
| 542 int len; | 542 int len; |
| 543 | 543 |
| 544 names = (CERTDistNames *)data; | 544 names = (CERTDistNames *)data; |
| 545 | 545 |
| 546 if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) { | 546 if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { |
| 547 » /* only collect names of CAs trusted for issuing SSL clients */ | 547 /* only collect names of CAs trusted for issuing SSL clients */ |
| 548 » if ( trust.sslFlags & CERTDB_TRUSTED_CLIENT_CA ) { | 548 if (trust.sslFlags & CERTDB_TRUSTED_CLIENT_CA) { |
| 549 » saveit = PR_TRUE; | 549 saveit = PR_TRUE; |
| 550 » } | 550 } |
| 551 } | 551 } |
| 552 | 552 |
| 553 if ( saveit ) { | 553 if (saveit) { |
| 554 » /* allocate the node */ | 554 /* allocate the node */ |
| 555 » node = (dnameNode*)PORT_ArenaAlloc(names->arena, sizeof(dnameNode)); | 555 node = (dnameNode *)PORT_ArenaAlloc(names->arena, sizeof(dnameNode)); |
| 556 » if ( node == NULL ) { | 556 if (node == NULL) { |
| 557 » return(SECFailure); | 557 return (SECFailure); |
| 558 » } | 558 } |
| 559 | 559 |
| 560 » /* copy the name */ | 560 /* copy the name */ |
| 561 » node->name.len = len = cert->derSubject.len; | 561 node->name.len = len = cert->derSubject.len; |
| 562 » node->name.type = siBuffer; | 562 node->name.type = siBuffer; |
| 563 » node->name.data = (unsigned char*)PORT_ArenaAlloc(names->arena, len); | 563 node->name.data = (unsigned char *)PORT_ArenaAlloc(names->arena, len); |
| 564 » if ( node->name.data == NULL ) { | 564 if (node->name.data == NULL) { |
| 565 » return(SECFailure); | 565 return (SECFailure); |
| 566 » } | 566 } |
| 567 » PORT_Memcpy(node->name.data, cert->derSubject.data, len); | 567 PORT_Memcpy(node->name.data, cert->derSubject.data, len); |
| 568 | 568 |
| 569 » /* link it into the list */ | 569 /* link it into the list */ |
| 570 » node->next = (dnameNode *)names->head; | 570 node->next = (dnameNode *)names->head; |
| 571 » names->head = (void *)node; | 571 names->head = (void *)node; |
| 572 | 572 |
| 573 » /* bump the count */ | 573 /* bump the count */ |
| 574 » names->nnames++; | 574 names->nnames++; |
| 575 } | 575 } |
| 576 | 576 |
| 577 return(SECSuccess); | 577 return (SECSuccess); |
| 578 } | 578 } |
| 579 | 579 |
| 580 /* | 580 /* |
| 581 * Return all of the CAs that are "trusted" for SSL. | 581 * Return all of the CAs that are "trusted" for SSL. |
| 582 */ | 582 */ |
| 583 CERTDistNames * | 583 CERTDistNames * |
| 584 CERT_DupDistNames(CERTDistNames *orig) | 584 CERT_DupDistNames(CERTDistNames *orig) |
| 585 { | 585 { |
| 586 PLArenaPool *arena; | 586 PLArenaPool *arena; |
| 587 CERTDistNames *names; | 587 CERTDistNames *names; |
| 588 int i; | 588 int i; |
| 589 SECStatus rv; | 589 SECStatus rv; |
| 590 | 590 |
| 591 /* allocate an arena to use */ | 591 /* allocate an arena to use */ |
| 592 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 592 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 593 if (arena == NULL) { | 593 if (arena == NULL) { |
| 594 » PORT_SetError(SEC_ERROR_NO_MEMORY); | 594 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 595 » return(NULL); | 595 return (NULL); |
| 596 } | 596 } |
| 597 | 597 |
| 598 /* allocate the header structure */ | 598 /* allocate the header structure */ |
| 599 names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); | 599 names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); |
| 600 if (names == NULL) { | 600 if (names == NULL) { |
| 601 » goto loser; | 601 goto loser; |
| 602 } | 602 } |
| 603 | 603 |
| 604 /* initialize the header struct */ | 604 /* initialize the header struct */ |
| 605 names->arena = arena; | 605 names->arena = arena; |
| 606 names->head = NULL; | 606 names->head = NULL; |
| 607 names->nnames = orig->nnames; | 607 names->nnames = orig->nnames; |
| 608 names->names = NULL; | 608 names->names = NULL; |
| 609 | 609 |
| 610 /* construct the array from the list */ | 610 /* construct the array from the list */ |
| 611 if (orig->nnames) { | 611 if (orig->nnames) { |
| 612 » names->names = (SECItem*)PORT_ArenaNewArray(arena, SECItem, | 612 names->names = (SECItem *)PORT_ArenaNewArray(arena, SECItem, |
| 613 orig->nnames); | 613 orig->nnames); |
| 614 » if (names->names == NULL) { | 614 if (names->names == NULL) { |
| 615 » goto loser; | 615 goto loser; |
| 616 » } | 616 } |
| 617 » for (i = 0; i < orig->nnames; i++) { | 617 for (i = 0; i < orig->nnames; i++) { |
| 618 rv = SECITEM_CopyItem(arena, &names->names[i], &orig->names[i]); | 618 rv = SECITEM_CopyItem(arena, &names->names[i], &orig->names[i]); |
| 619 if (rv != SECSuccess) { | 619 if (rv != SECSuccess) { |
| 620 goto loser; | 620 goto loser; |
| 621 } | 621 } |
| 622 } | 622 } |
| 623 } | 623 } |
| 624 return(names); | 624 return (names); |
| 625 | 625 |
| 626 loser: | 626 loser: |
| 627 PORT_FreeArena(arena, PR_FALSE); | 627 PORT_FreeArena(arena, PR_FALSE); |
| 628 return(NULL); | 628 return (NULL); |
| 629 } | 629 } |
| 630 | 630 |
| 631 CERTDistNames * | 631 CERTDistNames * |
| 632 CERT_GetSSLCACerts(CERTCertDBHandle *handle) | 632 CERT_GetSSLCACerts(CERTCertDBHandle *handle) |
| 633 { | 633 { |
| 634 PLArenaPool *arena; | 634 PLArenaPool *arena; |
| 635 CERTDistNames *names; | 635 CERTDistNames *names; |
| 636 int i; | 636 int i; |
| 637 SECStatus rv; | 637 SECStatus rv; |
| 638 dnameNode *node; | 638 dnameNode *node; |
| 639 | 639 |
| 640 /* allocate an arena to use */ | 640 /* allocate an arena to use */ |
| 641 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 641 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 642 if ( arena == NULL ) { | 642 if (arena == NULL) { |
| 643 » PORT_SetError(SEC_ERROR_NO_MEMORY); | 643 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 644 » return(NULL); | 644 return (NULL); |
| 645 } | 645 } |
| 646 | 646 |
| 647 /* allocate the header structure */ | 647 /* allocate the header structure */ |
| 648 names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); | 648 names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); |
| 649 if ( names == NULL ) { | 649 if (names == NULL) { |
| 650 » goto loser; | 650 goto loser; |
| 651 } | 651 } |
| 652 | 652 |
| 653 /* initialize the header struct */ | 653 /* initialize the header struct */ |
| 654 names->arena = arena; | 654 names->arena = arena; |
| 655 names->head = NULL; | 655 names->head = NULL; |
| 656 names->nnames = 0; | 656 names->nnames = 0; |
| 657 names->names = NULL; | 657 names->names = NULL; |
| 658 | 658 |
| 659 /* collect the names from the database */ | 659 /* collect the names from the database */ |
| 660 rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL); | 660 rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL); |
| 661 if ( rv ) { | 661 if (rv) { |
| 662 » goto loser; | 662 goto loser; |
| 663 } | 663 } |
| 664 | 664 |
| 665 /* construct the array from the list */ | 665 /* construct the array from the list */ |
| 666 if ( names->nnames ) { | 666 if (names->nnames) { |
| 667 » names->names = (SECItem*)PORT_ArenaAlloc(arena, names->nnames * sizeof(S
ECItem)); | 667 names->names = (SECItem *)PORT_ArenaAlloc(arena, names->nnames * sizeof(
SECItem)); |
| 668 | 668 |
| 669 » if ( names->names == NULL ) { | 669 if (names->names == NULL) { |
| 670 » goto loser; | 670 goto loser; |
| 671 » } | 671 } |
| 672 | |
| 673 » node = (dnameNode *)names->head; | |
| 674 » | |
| 675 » for ( i = 0; i < names->nnames; i++ ) { | |
| 676 » PORT_Assert(node != NULL); | |
| 677 » | |
| 678 » names->names[i] = node->name; | |
| 679 » node = node->next; | |
| 680 » } | |
| 681 | 672 |
| 682 » PORT_Assert(node == NULL); | 673 node = (dnameNode *)names->head; |
| 674 |
| 675 for (i = 0; i < names->nnames; i++) { |
| 676 PORT_Assert(node != NULL); |
| 677 |
| 678 names->names[i] = node->name; |
| 679 node = node->next; |
| 680 } |
| 681 |
| 682 PORT_Assert(node == NULL); |
| 683 } | 683 } |
| 684 | 684 |
| 685 return(names); | 685 return (names); |
| 686 | 686 |
| 687 loser: | 687 loser: |
| 688 PORT_FreeArena(arena, PR_FALSE); | 688 PORT_FreeArena(arena, PR_FALSE); |
| 689 return(NULL); | 689 return (NULL); |
| 690 } | 690 } |
| 691 | 691 |
| 692 CERTDistNames * | 692 CERTDistNames * |
| 693 CERT_DistNamesFromCertList(CERTCertList *certList) | 693 CERT_DistNamesFromCertList(CERTCertList *certList) |
| 694 { | 694 { |
| 695 CERTDistNames * dnames = NULL; | 695 CERTDistNames *dnames = NULL; |
| 696 PLArenaPool * arena; | 696 PLArenaPool *arena; |
| 697 CERTCertListNode *node = NULL; | 697 CERTCertListNode *node = NULL; |
| 698 SECItem * names = NULL; | 698 SECItem *names = NULL; |
| 699 int listLen = 0, i = 0; | 699 int listLen = 0, i = 0; |
| 700 | 700 |
| 701 if (certList == NULL) { | 701 if (certList == NULL) { |
| 702 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 702 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 703 return NULL; | 703 return NULL; |
| 704 } | 704 } |
| 705 | 705 |
| 706 node = CERT_LIST_HEAD(certList); | 706 node = CERT_LIST_HEAD(certList); |
| 707 while ( ! CERT_LIST_END(node, certList) ) { | 707 while (!CERT_LIST_END(node, certList)) { |
| 708 listLen += 1; | 708 listLen += 1; |
| 709 node = CERT_LIST_NEXT(node); | 709 node = CERT_LIST_NEXT(node); |
| 710 } | 710 } |
| 711 | 711 |
| 712 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 712 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 713 if (arena == NULL) goto loser; | 713 if (arena == NULL) |
| 714 goto loser; |
| 714 dnames = PORT_ArenaZNew(arena, CERTDistNames); | 715 dnames = PORT_ArenaZNew(arena, CERTDistNames); |
| 715 if (dnames == NULL) goto loser; | 716 if (dnames == NULL) |
| 717 goto loser; |
| 716 | 718 |
| 717 dnames->arena = arena; | 719 dnames->arena = arena; |
| 718 dnames->nnames = listLen; | 720 dnames->nnames = listLen; |
| 719 dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen); | 721 dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen); |
| 720 if (names == NULL) goto loser; | 722 if (names == NULL) |
| 723 goto loser; |
| 721 | 724 |
| 722 node = CERT_LIST_HEAD(certList); | 725 node = CERT_LIST_HEAD(certList); |
| 723 while ( ! CERT_LIST_END(node, certList) ) { | 726 while (!CERT_LIST_END(node, certList)) { |
| 724 CERTCertificate *cert = node->cert; | 727 CERTCertificate *cert = node->cert; |
| 725 SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject); | 728 SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject); |
| 726 if (rv == SECFailure) { | 729 if (rv == SECFailure) { |
| 727 goto loser; | 730 goto loser; |
| 728 } | 731 } |
| 729 node = CERT_LIST_NEXT(node); | 732 node = CERT_LIST_NEXT(node); |
| 730 } | 733 } |
| 731 return dnames; | 734 return dnames; |
| 732 loser: | 735 loser: |
| 733 if (arena) { | 736 if (arena) { |
| 734 PORT_FreeArena(arena, PR_FALSE); | 737 PORT_FreeArena(arena, PR_FALSE); |
| 735 } | 738 } |
| 736 return NULL; | 739 return NULL; |
| 737 } | 740 } |
| 738 | 741 |
| 739 CERTDistNames * | 742 CERTDistNames * |
| 740 CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, | 743 CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, |
| 741 » » » int nnames) | 744 int nnames) |
| 742 { | 745 { |
| 743 CERTDistNames *dnames = NULL; | 746 CERTDistNames *dnames = NULL; |
| 744 PLArenaPool *arena; | 747 PLArenaPool *arena; |
| 745 int i, rv; | 748 int i, rv; |
| 746 SECItem *names = NULL; | 749 SECItem *names = NULL; |
| 747 CERTCertificate *cert = NULL; | 750 CERTCertificate *cert = NULL; |
| 748 | 751 |
| 749 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 752 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 750 if (arena == NULL) goto loser; | 753 if (arena == NULL) |
| 754 goto loser; |
| 751 dnames = PORT_ArenaZNew(arena, CERTDistNames); | 755 dnames = PORT_ArenaZNew(arena, CERTDistNames); |
| 752 if (dnames == NULL) goto loser; | 756 if (dnames == NULL) |
| 757 goto loser; |
| 753 | 758 |
| 754 dnames->arena = arena; | 759 dnames->arena = arena; |
| 755 dnames->nnames = nnames; | 760 dnames->nnames = nnames; |
| 756 dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames); | 761 dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames); |
| 757 if (names == NULL) goto loser; | 762 if (names == NULL) |
| 758 | 763 goto loser; |
| 764 |
| 759 for (i = 0; i < nnames; i++) { | 765 for (i = 0; i < nnames; i++) { |
| 760 » cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]); | 766 cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]); |
| 761 » if (cert == NULL) goto loser; | 767 if (cert == NULL) |
| 762 » rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject); | 768 goto loser; |
| 763 » if (rv == SECFailure) goto loser; | 769 rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject); |
| 764 » CERT_DestroyCertificate(cert); | 770 if (rv == SECFailure) |
| 771 goto loser; |
| 772 CERT_DestroyCertificate(cert); |
| 765 } | 773 } |
| 766 return dnames; | 774 return dnames; |
| 767 | 775 |
| 768 loser: | 776 loser: |
| 769 if (cert != NULL) | 777 if (cert != NULL) |
| 770 » CERT_DestroyCertificate(cert); | 778 CERT_DestroyCertificate(cert); |
| 771 if (arena != NULL) | 779 if (arena != NULL) |
| 772 » PORT_FreeArena(arena, PR_FALSE); | 780 PORT_FreeArena(arena, PR_FALSE); |
| 773 return NULL; | 781 return NULL; |
| 774 } | 782 } |
| 775 | 783 |
| 776 /* [ from pcertdb.c - calls Ascii to Name ] */ | 784 /* [ from pcertdb.c - calls Ascii to Name ] */ |
| 777 /* | 785 /* |
| 778 * Lookup a certificate in the database by name | 786 * Lookup a certificate in the database by name |
| 779 */ | 787 */ |
| 780 CERTCertificate * | 788 CERTCertificate * |
| 781 CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr) | 789 CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr) |
| 782 { | 790 { |
| 783 CERTName *name; | 791 CERTName *name; |
| 784 SECItem *nameItem; | 792 SECItem *nameItem; |
| 785 CERTCertificate *cert = NULL; | 793 CERTCertificate *cert = NULL; |
| 786 PLArenaPool *arena = NULL; | 794 PLArenaPool *arena = NULL; |
| 787 | 795 |
| 788 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 796 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 789 | 797 |
| 790 if ( arena == NULL ) { | 798 if (arena == NULL) { |
| 791 » goto loser; | 799 goto loser; |
| 792 } | 800 } |
| 793 | 801 |
| 794 name = CERT_AsciiToName(nameStr); | 802 name = CERT_AsciiToName(nameStr); |
| 795 | 803 |
| 796 if ( name ) { | 804 if (name) { |
| 797 » nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name, | 805 nameItem = SEC_ASN1EncodeItem(arena, NULL, (void *)name, |
| 798 » » » » CERT_NameTemplate); | 806 CERT_NameTemplate); |
| 799 » if ( nameItem != NULL ) { | 807 if (nameItem != NULL) { |
| 800 cert = CERT_FindCertByName(handle, nameItem); | 808 cert = CERT_FindCertByName(handle, nameItem); |
| 801 » } | 809 } |
| 802 » CERT_DestroyName(name); | 810 CERT_DestroyName(name); |
| 803 } | 811 } |
| 804 | 812 |
| 805 loser: | 813 loser: |
| 806 if ( arena ) { | 814 if (arena) { |
| 807 » PORT_FreeArena(arena, PR_FALSE); | 815 PORT_FreeArena(arena, PR_FALSE); |
| 808 } | 816 } |
| 809 | 817 |
| 810 return(cert); | 818 return (cert); |
| 811 } | 819 } |
| 812 | 820 |
| 813 /* From certv3.c */ | 821 /* From certv3.c */ |
| 814 | 822 |
| 815 CERTCrlDistributionPoints * | 823 CERTCrlDistributionPoints * |
| 816 CERT_FindCRLDistributionPoints (CERTCertificate *cert) | 824 CERT_FindCRLDistributionPoints(CERTCertificate *cert) |
| 817 { | 825 { |
| 818 SECItem encodedExtenValue; | 826 SECItem encodedExtenValue; |
| 819 SECStatus rv; | 827 SECStatus rv; |
| 820 CERTCrlDistributionPoints *dps; | 828 CERTCrlDistributionPoints *dps; |
| 821 | 829 |
| 822 encodedExtenValue.data = NULL; | 830 encodedExtenValue.data = NULL; |
| 823 encodedExtenValue.len = 0; | 831 encodedExtenValue.len = 0; |
| 824 | 832 |
| 825 rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS, | 833 rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS, |
| 826 » » » &encodedExtenValue); | 834 &encodedExtenValue); |
| 827 if ( rv != SECSuccess ) { | 835 if (rv != SECSuccess) { |
| 828 » return (NULL); | 836 return (NULL); |
| 829 } | 837 } |
| 830 | 838 |
| 831 dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue); | 839 dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue); |
| 832 | 840 |
| 833 PORT_Free(encodedExtenValue.data); | 841 PORT_Free(encodedExtenValue.data); |
| 834 | 842 |
| 835 return dps; | 843 return dps; |
| 836 } | 844 } |
| 837 | 845 |
| 838 /* From crl.c */ | 846 /* From crl.c */ |
| 839 CERTSignedCrl * CERT_ImportCRL | 847 CERTSignedCrl * |
| 840 (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx) | 848 CERT_ImportCRL(CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, v
oid *wincx) |
| 841 { | 849 { |
| 842 CERTSignedCrl* retCrl = NULL; | 850 CERTSignedCrl *retCrl = NULL; |
| 843 PK11SlotInfo* slot = PK11_GetInternalKeySlot(); | 851 PK11SlotInfo *slot = PK11_GetInternalKeySlot(); |
| 844 retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx, | 852 retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx, |
| 845 CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS); | 853 CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT
_OPTIONS); |
| 846 PK11_FreeSlot(slot); | 854 PK11_FreeSlot(slot); |
| 847 | 855 |
| 848 return retCrl; | 856 return retCrl; |
| 849 } | 857 } |
| 850 | 858 |
| 851 /* From certdb.c */ | 859 /* From certdb.c */ |
| 852 static SECStatus | 860 static SECStatus |
| 853 cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
trusted) | 861 cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
trusted) |
| 854 { | 862 { |
| 855 SECStatus rv; | 863 SECStatus rv; |
| 856 SECItem *derCert; | 864 SECItem *derCert; |
| 857 CERTCertificate *cert = NULL; | 865 CERTCertificate *cert = NULL; |
| 858 CERTCertificate *newcert = NULL; | 866 CERTCertificate *newcert = NULL; |
| 859 CERTCertDBHandle *handle; | 867 CERTCertDBHandle *handle; |
| 860 CERTCertTrust trust; | 868 CERTCertTrust trust; |
| 861 PRBool isca; | 869 PRBool isca; |
| 862 char *nickname; | 870 char *nickname; |
| 863 unsigned int certtype; | 871 unsigned int certtype; |
| 864 | 872 |
| 865 handle = CERT_GetDefaultCertDB(); | 873 handle = CERT_GetDefaultCertDB(); |
| 866 | 874 |
| 867 while (numcerts--) { | 875 while (numcerts--) { |
| 868 » derCert = certs; | 876 derCert = certs; |
| 869 » certs++; | 877 certs++; |
| 870 | 878 |
| 871 » /* decode my certificate */ | 879 /* decode my certificate */ |
| 872 » /* This use is ok -- only looks at decoded parts, calls NewTemp later */ | 880 /* This use is ok -- only looks at decoded parts, calls NewTemp later */ |
| 873 » newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); | 881 newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); |
| 874 » if ( newcert == NULL ) { | 882 if (newcert == NULL) { |
| 875 » goto loser; | 883 goto loser; |
| 876 » } | 884 } |
| 877 | 885 |
| 878 » if (!trusted) { | 886 if (!trusted) { |
| 879 » /* make sure that cert is valid */ | 887 /* make sure that cert is valid */ |
| 880 » rv = CERT_CertTimesValid(newcert); | 888 rv = CERT_CertTimesValid(newcert); |
| 881 » if ( rv == SECFailure ) { | 889 if (rv == SECFailure) { |
| 882 » » goto endloop; | 890 goto endloop; |
| 883 » } | 891 } |
| 884 » } | 892 } |
| 885 | 893 |
| 886 » /* does it have the CA extension */ | 894 /* does it have the CA extension */ |
| 887 » | 895 |
| 888 » /* | 896 /* |
| 889 * Make sure that if this is an intermediate CA in the chain that | 897 * Make sure that if this is an intermediate CA in the chain that |
| 890 * it was given permission by its signer to be a CA. | 898 * it was given permission by its signer to be a CA. |
| 891 */ | 899 */ |
| 892 » isca = CERT_IsCACert(newcert, &certtype); | 900 isca = CERT_IsCACert(newcert, &certtype); |
| 893 | 901 |
| 894 » if ( !isca ) { | 902 if (!isca) { |
| 895 » if (!trusted) { | 903 if (!trusted) { |
| 896 » » goto endloop; | 904 goto endloop; |
| 897 » } | 905 } |
| 898 » trust.sslFlags = CERTDB_VALID_CA; | 906 trust.sslFlags = CERTDB_VALID_CA; |
| 899 » trust.emailFlags = CERTDB_VALID_CA; | 907 trust.emailFlags = CERTDB_VALID_CA; |
| 900 » trust.objectSigningFlags = CERTDB_VALID_CA; | 908 trust.objectSigningFlags = CERTDB_VALID_CA; |
| 901 » } else { | 909 } else { |
| 902 » /* SSL ca's must have the ssl bit set */ | 910 /* SSL ca's must have the ssl bit set */ |
| 903 » if ( ( certUsage == certUsageSSLCA ) && | 911 if ((certUsage == certUsageSSLCA) && |
| 904 » » (( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA )) { | 912 ((certtype & NS_CERT_TYPE_SSL_CA) != NS_CERT_TYPE_SSL_CA)) { |
| 905 » » goto endloop; | 913 goto endloop; |
| 906 » } | 914 } |
| 907 | 915 |
| 908 » /* it passed all of the tests, so lets add it to the database */ | 916 /* it passed all of the tests, so lets add it to the database */ |
| 909 » /* mark it as a CA */ | 917 /* mark it as a CA */ |
| 910 » PORT_Memset((void *)&trust, 0, sizeof(trust)); | 918 PORT_Memset((void *)&trust, 0, sizeof(trust)); |
| 911 » switch ( certUsage ) { | 919 switch (certUsage) { |
| 912 » case certUsageSSLCA: | 920 case certUsageSSLCA: |
| 913 » » trust.sslFlags = CERTDB_VALID_CA; | 921 trust.sslFlags = CERTDB_VALID_CA; |
| 914 » » break; | 922 break; |
| 915 » case certUsageUserCertImport: | 923 case certUsageUserCertImport: |
| 916 » » if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) { | 924 if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA)
{ |
| 917 » » trust.sslFlags = CERTDB_VALID_CA; | 925 trust.sslFlags = CERTDB_VALID_CA; |
| 918 » » } | 926 } |
| 919 » » if ((certtype & NS_CERT_TYPE_EMAIL_CA) | 927 if ((certtype & NS_CERT_TYPE_EMAIL_CA) == |
| 920 » » » » » » == NS_CERT_TYPE_EMAIL_CA ) { | 928 NS_CERT_TYPE_EMAIL_CA) { |
| 921 » » trust.emailFlags = CERTDB_VALID_CA; | 929 trust.emailFlags = CERTDB_VALID_CA; |
| 922 » » } | 930 } |
| 923 » » if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) == | 931 if ((certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA) == |
| 924 » » » » » NS_CERT_TYPE_OBJECT_SIGNING_CA ) { | 932 NS_CERT_TYPE_OBJECT_SIGNING_CA) { |
| 925 » » trust.objectSigningFlags = CERTDB_VALID_CA; | 933 trust.objectSigningFlags = CERTDB_VALID_CA; |
| 926 » » } | 934 } |
| 927 » » break; | 935 break; |
| 928 » default: | 936 default: |
| 929 » » PORT_Assert(0); | 937 PORT_Assert(0); |
| 930 » » break; | 938 break; |
| 931 » } | 939 } |
| 932 » } | 940 } |
| 933 » | |
| 934 » cert = CERT_NewTempCertificate(handle, derCert, NULL, | |
| 935 » » » » » » » PR_FALSE, PR_FALSE); | |
| 936 » if ( cert == NULL ) { | |
| 937 » goto loser; | |
| 938 » } | |
| 939 » | |
| 940 » /* if the cert is temp, make it perm; otherwise we're done */ | |
| 941 » if (cert->istemp) { | |
| 942 » /* get a default nickname for it */ | |
| 943 » nickname = CERT_MakeCANickname(cert); | |
| 944 | 941 |
| 945 » rv = CERT_AddTempCertToPerm(cert, nickname, &trust); | 942 cert = CERT_NewTempCertificate(handle, derCert, NULL, |
| 943 PR_FALSE, PR_FALSE); |
| 944 if (cert == NULL) { |
| 945 goto loser; |
| 946 } |
| 946 | 947 |
| 947 » /* free the nickname */ | 948 /* if the cert is temp, make it perm; otherwise we're done */ |
| 948 » if ( nickname ) { | 949 if (cert->istemp) { |
| 949 » » PORT_Free(nickname); | 950 /* get a default nickname for it */ |
| 950 » } | 951 nickname = CERT_MakeCANickname(cert); |
| 951 » } else { | |
| 952 » rv = SECSuccess; | |
| 953 » } | |
| 954 | 952 |
| 955 » CERT_DestroyCertificate(cert); | 953 rv = CERT_AddTempCertToPerm(cert, nickname, &trust); |
| 956 » cert = NULL; | |
| 957 » | |
| 958 » if ( rv != SECSuccess ) { | |
| 959 » goto loser; | |
| 960 » } | |
| 961 | 954 |
| 962 endloop: | 955 /* free the nickname */ |
| 963 » if ( newcert ) { | 956 if (nickname) { |
| 964 » CERT_DestroyCertificate(newcert); | 957 PORT_Free(nickname); |
| 965 » newcert = NULL; | 958 } |
| 966 » } | 959 } else { |
| 967 » | 960 rv = SECSuccess; |
| 961 } |
| 962 |
| 963 CERT_DestroyCertificate(cert); |
| 964 cert = NULL; |
| 965 |
| 966 if (rv != SECSuccess) { |
| 967 goto loser; |
| 968 } |
| 969 |
| 970 endloop: |
| 971 if (newcert) { |
| 972 CERT_DestroyCertificate(newcert); |
| 973 newcert = NULL; |
| 974 } |
| 968 } | 975 } |
| 969 | 976 |
| 970 rv = SECSuccess; | 977 rv = SECSuccess; |
| 971 goto done; | 978 goto done; |
| 972 loser: | 979 loser: |
| 973 rv = SECFailure; | 980 rv = SECFailure; |
| 974 done: | 981 done: |
| 975 | 982 |
| 976 if ( newcert ) { | 983 if (newcert) { |
| 977 » CERT_DestroyCertificate(newcert); | 984 CERT_DestroyCertificate(newcert); |
| 978 » newcert = NULL; | 985 newcert = NULL; |
| 979 } | 986 } |
| 980 | 987 |
| 981 if ( cert ) { | 988 if (cert) { |
| 982 » CERT_DestroyCertificate(cert); | 989 CERT_DestroyCertificate(cert); |
| 983 » cert = NULL; | 990 cert = NULL; |
| 984 } | 991 } |
| 985 | 992 |
| 986 return(rv); | 993 return (rv); |
| 987 } | 994 } |
| 988 | 995 |
| 989 SECStatus | 996 SECStatus |
| 990 CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage) | 997 CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage) |
| 991 { | 998 { |
| 992 return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE); | 999 return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE); |
| 993 } | 1000 } |
| 994 | 1001 |
| 995 SECStatus | 1002 SECStatus |
| 996 CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage)
{ | 1003 CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage) |
| 1004 { |
| 997 return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE); | 1005 return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE); |
| 998 } | 1006 } |
| 999 | 1007 |
| 1000 /* Moved from certdb.c */ | 1008 /* Moved from certdb.c */ |
| 1001 /* | 1009 /* |
| 1002 ** CERT_CertChainFromCert | 1010 ** CERT_CertChainFromCert |
| 1003 ** | 1011 ** |
| 1004 ** Construct a CERTCertificateList consisting of the given certificate and all | 1012 ** Construct a CERTCertificateList consisting of the given certificate and all |
| 1005 ** of the issuer certs until we either get to a self-signed cert or can't find | 1013 ** of the issuer certs until we either get to a self-signed cert or can't find |
| 1006 ** an issuer. Since we don't know how many certs are in the chain we have to | 1014 ** an issuer. Since we don't know how many certs are in the chain we have to |
| 1007 ** build a linked list first as we count them. | 1015 ** build a linked list first as we count them. |
| 1008 */ | 1016 */ |
| 1009 | 1017 |
| 1010 typedef struct certNode { | 1018 typedef struct certNode { |
| 1011 struct certNode *next; | 1019 struct certNode *next; |
| 1012 CERTCertificate *cert; | 1020 CERTCertificate *cert; |
| 1013 } certNode; | 1021 } certNode; |
| 1014 | 1022 |
| 1015 CERTCertificateList * | 1023 CERTCertificateList * |
| 1016 CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, | 1024 CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, |
| 1017 » » PRBool includeRoot) | 1025 PRBool includeRoot) |
| 1018 { | 1026 { |
| 1019 CERTCertificateList *chain = NULL; | 1027 CERTCertificateList *chain = NULL; |
| 1020 NSSCertificate **stanChain; | 1028 NSSCertificate **stanChain; |
| 1021 NSSCertificate *stanCert; | 1029 NSSCertificate *stanCert; |
| 1022 PLArenaPool *arena; | 1030 PLArenaPool *arena; |
| 1023 NSSUsage nssUsage; | 1031 NSSUsage nssUsage; |
| 1024 int i, len; | 1032 int i, len; |
| 1025 NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); | 1033 NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); |
| 1026 NSSCryptoContext *cc = STAN_GetDefaultCryptoContext(); | 1034 NSSCryptoContext *cc = STAN_GetDefaultCryptoContext(); |
| 1027 | 1035 |
| 1028 stanCert = STAN_GetNSSCertificate(cert); | 1036 stanCert = STAN_GetNSSCertificate(cert); |
| 1029 if (!stanCert) { | 1037 if (!stanCert) { |
| 1030 /* error code is set */ | 1038 /* error code is set */ |
| 1031 return NULL; | 1039 return NULL; |
| 1032 } | 1040 } |
| 1033 nssUsage.anyUsage = PR_FALSE; | 1041 nssUsage.anyUsage = PR_FALSE; |
| 1034 nssUsage.nss3usage = usage; | 1042 nssUsage.nss3usage = usage; |
| 1035 nssUsage.nss3lookingForCA = PR_FALSE; | 1043 nssUsage.nss3lookingForCA = PR_FALSE; |
| 1036 stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL, | 1044 stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL, |
| 1037 » » » » » CERT_MAX_CERT_CHAIN, NULL, NULL, td, c
c); | 1045 CERT_MAX_CERT_CHAIN, NULL, NULL, td, c
c); |
| 1038 if (!stanChain) { | 1046 if (!stanChain) { |
| 1039 » PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 1047 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); |
| 1040 » return NULL; | 1048 return NULL; |
| 1041 } | 1049 } |
| 1042 | 1050 |
| 1043 len = 0; | 1051 len = 0; |
| 1044 stanCert = stanChain[0]; | 1052 stanCert = stanChain[0]; |
| 1045 while (stanCert) { | 1053 while (stanCert) { |
| 1046 » stanCert = stanChain[++len]; | 1054 stanCert = stanChain[++len]; |
| 1047 } | 1055 } |
| 1048 | 1056 |
| 1049 arena = PORT_NewArena(4096); | 1057 arena = PORT_NewArena(4096); |
| 1050 if (arena == NULL) { | 1058 if (arena == NULL) { |
| 1051 » goto loser; | 1059 goto loser; |
| 1052 } | 1060 } |
| 1053 | 1061 |
| 1054 chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, | 1062 chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, |
| 1055 sizeof(CERTCertificateList)); | 1063 sizeof(CERTCertificateList)); |
| 1056 if (!chain) goto loser; | 1064 if (!chain) |
| 1057 chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); | 1065 goto loser; |
| 1058 if (!chain->certs) goto loser; | 1066 chain->certs = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); |
| 1067 if (!chain->certs) |
| 1068 goto loser; |
| 1059 i = 0; | 1069 i = 0; |
| 1060 stanCert = stanChain[i]; | 1070 stanCert = stanChain[i]; |
| 1061 while (stanCert) { | 1071 while (stanCert) { |
| 1062 » SECItem derCert; | 1072 SECItem derCert; |
| 1063 » CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); | 1073 CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); |
| 1064 » if (!cCert) { | 1074 if (!cCert) { |
| 1065 » goto loser; | 1075 goto loser; |
| 1066 » } | 1076 } |
| 1067 » derCert.len = (unsigned int)stanCert->encoding.size; | 1077 derCert.len = (unsigned int)stanCert->encoding.size; |
| 1068 » derCert.data = (unsigned char *)stanCert->encoding.data; | 1078 derCert.data = (unsigned char *)stanCert->encoding.data; |
| 1069 » derCert.type = siBuffer; | 1079 derCert.type = siBuffer; |
| 1070 » SECITEM_CopyItem(arena, &chain->certs[i], &derCert); | 1080 SECITEM_CopyItem(arena, &chain->certs[i], &derCert); |
| 1071 » stanCert = stanChain[++i]; | 1081 stanCert = stanChain[++i]; |
| 1072 » if (!stanCert && !cCert->isRoot) { | 1082 if (!stanCert && !cCert->isRoot) { |
| 1073 » /* reached the end of the chain, but the final cert is | 1083 /* reached the end of the chain, but the final cert is |
| 1074 * not a root. Don't discard it. | 1084 * not a root. Don't discard it. |
| 1075 */ | 1085 */ |
| 1076 » includeRoot = PR_TRUE; | 1086 includeRoot = PR_TRUE; |
| 1077 » } | 1087 } |
| 1078 » CERT_DestroyCertificate(cCert); | 1088 CERT_DestroyCertificate(cCert); |
| 1079 } | 1089 } |
| 1080 if ( !includeRoot && len > 1) { | 1090 if (!includeRoot && len > 1) { |
| 1081 » chain->len = len - 1; | 1091 chain->len = len - 1; |
| 1082 } else { | 1092 } else { |
| 1083 » chain->len = len; | 1093 chain->len = len; |
| 1084 } | 1094 } |
| 1085 | 1095 |
| 1086 chain->arena = arena; | 1096 chain->arena = arena; |
| 1087 nss_ZFreeIf(stanChain); | 1097 nss_ZFreeIf(stanChain); |
| 1088 return chain; | 1098 return chain; |
| 1089 loser: | 1099 loser: |
| 1090 i = 0; | 1100 i = 0; |
| 1091 stanCert = stanChain[i]; | 1101 stanCert = stanChain[i]; |
| 1092 while (stanCert) { | 1102 while (stanCert) { |
| 1093 » CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); | 1103 CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); |
| 1094 » if (cCert) { | 1104 if (cCert) { |
| 1095 » CERT_DestroyCertificate(cCert); | 1105 CERT_DestroyCertificate(cCert); |
| 1096 » } | 1106 } |
| 1097 » stanCert = stanChain[++i]; | 1107 stanCert = stanChain[++i]; |
| 1098 } | 1108 } |
| 1099 nss_ZFreeIf(stanChain); | 1109 nss_ZFreeIf(stanChain); |
| 1100 if (arena) { | 1110 if (arena) { |
| 1101 » PORT_FreeArena(arena, PR_FALSE); | 1111 PORT_FreeArena(arena, PR_FALSE); |
| 1102 } | 1112 } |
| 1103 return NULL; | 1113 return NULL; |
| 1104 } | 1114 } |
| 1105 | 1115 |
| 1106 /* Builds a CERTCertificateList holding just one DER-encoded cert, namely | 1116 /* Builds a CERTCertificateList holding just one DER-encoded cert, namely |
| 1107 ** the one for the cert passed as an argument. | 1117 ** the one for the cert passed as an argument. |
| 1108 */ | 1118 */ |
| 1109 CERTCertificateList * | 1119 CERTCertificateList * |
| 1110 CERT_CertListFromCert(CERTCertificate *cert) | 1120 CERT_CertListFromCert(CERTCertificate *cert) |
| 1111 { | 1121 { |
| 1112 CERTCertificateList *chain = NULL; | 1122 CERTCertificateList *chain = NULL; |
| 1113 int rv; | 1123 int rv; |
| 1114 PLArenaPool *arena; | 1124 PLArenaPool *arena; |
| 1115 | 1125 |
| 1116 /* arena for SecCertificateList */ | 1126 /* arena for SecCertificateList */ |
| 1117 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1127 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 1118 if (arena == NULL) goto no_memory; | 1128 if (arena == NULL) |
| 1129 goto no_memory; |
| 1119 | 1130 |
| 1120 /* build the CERTCertificateList */ | 1131 /* build the CERTCertificateList */ |
| 1121 chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificate
List)); | 1132 chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificate
List)); |
| 1122 if (chain == NULL) goto no_memory; | 1133 if (chain == NULL) |
| 1123 chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem)); | 1134 goto no_memory; |
| 1124 if (chain->certs == NULL) goto no_memory; | 1135 chain->certs = (SECItem *)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem)); |
| 1136 if (chain->certs == NULL) |
| 1137 goto no_memory; |
| 1125 rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert)); | 1138 rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert)); |
| 1126 if (rv < 0) goto loser; | 1139 if (rv < 0) |
| 1140 goto loser; |
| 1127 chain->len = 1; | 1141 chain->len = 1; |
| 1128 chain->arena = arena; | 1142 chain->arena = arena; |
| 1129 | 1143 |
| 1130 return chain; | 1144 return chain; |
| 1131 | 1145 |
| 1132 no_memory: | 1146 no_memory: |
| 1133 PORT_SetError(SEC_ERROR_NO_MEMORY); | 1147 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1134 loser: | 1148 loser: |
| 1135 if (arena != NULL) { | 1149 if (arena != NULL) { |
| 1136 » PORT_FreeArena(arena, PR_FALSE); | 1150 PORT_FreeArena(arena, PR_FALSE); |
| 1137 } | 1151 } |
| 1138 return NULL; | 1152 return NULL; |
| 1139 } | 1153 } |
| 1140 | 1154 |
| 1141 CERTCertificateList * | 1155 CERTCertificateList * |
| 1142 CERT_DupCertList(const CERTCertificateList * oldList) | 1156 CERT_DupCertList(const CERTCertificateList *oldList) |
| 1143 { | 1157 { |
| 1144 CERTCertificateList *newList = NULL; | 1158 CERTCertificateList *newList = NULL; |
| 1145 PLArenaPool *arena = NULL; | 1159 PLArenaPool *arena = NULL; |
| 1146 SECItem *newItem; | 1160 SECItem *newItem; |
| 1147 SECItem *oldItem; | 1161 SECItem *oldItem; |
| 1148 int len = oldList->len; | 1162 int len = oldList->len; |
| 1149 int rv; | 1163 int rv; |
| 1150 | 1164 |
| 1151 /* arena for SecCertificateList */ | 1165 /* arena for SecCertificateList */ |
| 1152 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1166 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 1153 if (arena == NULL) | 1167 if (arena == NULL) |
| 1154 » goto no_memory; | 1168 goto no_memory; |
| 1155 | 1169 |
| 1156 /* now build the CERTCertificateList */ | 1170 /* now build the CERTCertificateList */ |
| 1157 newList = PORT_ArenaNew(arena, CERTCertificateList); | 1171 newList = PORT_ArenaNew(arena, CERTCertificateList); |
| 1158 if (newList == NULL) | 1172 if (newList == NULL) |
| 1159 » goto no_memory; | 1173 goto no_memory; |
| 1160 newList->arena = arena; | 1174 newList->arena = arena; |
| 1161 newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); | 1175 newItem = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); |
| 1162 if (newItem == NULL) | 1176 if (newItem == NULL) |
| 1163 » goto no_memory; | 1177 goto no_memory; |
| 1164 newList->certs = newItem; | 1178 newList->certs = newItem; |
| 1165 newList->len = len; | 1179 newList->len = len; |
| 1166 | 1180 |
| 1167 for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) { | 1181 for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) { |
| 1168 » rv = SECITEM_CopyItem(arena, newItem, oldItem); | 1182 rv = SECITEM_CopyItem(arena, newItem, oldItem); |
| 1169 » if (rv < 0) | 1183 if (rv < 0) |
| 1170 » goto loser; | 1184 goto loser; |
| 1171 } | 1185 } |
| 1172 return newList; | 1186 return newList; |
| 1173 | 1187 |
| 1174 no_memory: | 1188 no_memory: |
| 1175 PORT_SetError(SEC_ERROR_NO_MEMORY); | 1189 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1176 loser: | 1190 loser: |
| 1177 if (arena != NULL) { | 1191 if (arena != NULL) { |
| 1178 » PORT_FreeArena(arena, PR_FALSE); | 1192 PORT_FreeArena(arena, PR_FALSE); |
| 1179 } | 1193 } |
| 1180 return NULL; | 1194 return NULL; |
| 1181 } | 1195 } |
| 1182 | 1196 |
| 1183 void | 1197 void |
| 1184 CERT_DestroyCertificateList(CERTCertificateList *list) | 1198 CERT_DestroyCertificateList(CERTCertificateList *list) |
| 1185 { | 1199 { |
| 1186 PORT_FreeArena(list->arena, PR_FALSE); | 1200 PORT_FreeArena(list->arena, PR_FALSE); |
| 1187 } | 1201 } |
| 1188 | |
| OLD | NEW |