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 | 4 |
5 /* | 5 /* |
6 * Implementation of OCSP services, for both client and server. | 6 * Implementation of OCSP services, for both client and server. |
7 * (XXX, really, mostly just for client right now, but intended to do both.) | 7 * (XXX, really, mostly just for client right now, but intended to do both.) |
8 * | 8 * |
9 * $Id: ocsp.c,v 1.71 2012/05/31 22:03:36 emaldona%redhat.com Exp $ | 9 * $Id: ocsp.c,v 1.72 2012/09/22 13:41:58 wtc%google.com Exp $ |
10 */ | 10 */ |
11 | 11 |
12 #include "prerror.h" | 12 #include "prerror.h" |
13 #include "prprf.h" | 13 #include "prprf.h" |
14 #include "plarena.h" | 14 #include "plarena.h" |
15 #include "prnetdb.h" | 15 #include "prnetdb.h" |
16 | 16 |
17 #include "seccomon.h" | 17 #include "seccomon.h" |
18 #include "secitem.h" | 18 #include "secitem.h" |
19 #include "secoidt.h" | 19 #include "secoidt.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 ocspMode_FailureIsVerificationFailure, | 98 ocspMode_FailureIsVerificationFailure, |
99 NULL | 99 NULL |
100 }; | 100 }; |
101 | 101 |
102 | 102 |
103 | 103 |
104 /* Forward declarations */ | 104 /* Forward declarations */ |
105 static SECItem * | 105 static SECItem * |
106 ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena, | 106 ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena, |
107 CERTOCSPRequest *request, | 107 CERTOCSPRequest *request, |
108 char *location, int64 time, | 108 const char *location, int64 time, |
109 PRBool addServiceLocator, | 109 PRBool addServiceLocator, |
110 void *pwArg, | 110 void *pwArg, |
111 CERTOCSPRequest **pRequest); | 111 CERTOCSPRequest **pRequest); |
112 static SECStatus | 112 static SECStatus |
113 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, | 113 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, |
114 CERTOCSPCertID *certID, | 114 CERTOCSPCertID *certID, |
115 CERTCertificate *cert, | 115 CERTCertificate *cert, |
116 int64 time, | 116 int64 time, |
117 void *pwArg, | 117 void *pwArg, |
118 PRBool *certIDWasConsumed, | 118 PRBool *certIDWasConsumed, |
(...skipping 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1469 * Decode a DER encoded OCSP Request. | 1469 * Decode a DER encoded OCSP Request. |
1470 * INPUTS: | 1470 * INPUTS: |
1471 * SECItem *src | 1471 * SECItem *src |
1472 * Pointer to a SECItem holding DER encoded OCSP Request. | 1472 * Pointer to a SECItem holding DER encoded OCSP Request. |
1473 * RETURN: | 1473 * RETURN: |
1474 * Returns a pointer to a CERTOCSPRequest containing the decoded request. | 1474 * Returns a pointer to a CERTOCSPRequest containing the decoded request. |
1475 * On error, returns NULL. Most likely error is trouble decoding | 1475 * On error, returns NULL. Most likely error is trouble decoding |
1476 * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory). | 1476 * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory). |
1477 */ | 1477 */ |
1478 CERTOCSPRequest * | 1478 CERTOCSPRequest * |
1479 CERT_DecodeOCSPRequest(SECItem *src) | 1479 CERT_DecodeOCSPRequest(const SECItem *src) |
1480 { | 1480 { |
1481 PRArenaPool *arena = NULL; | 1481 PRArenaPool *arena = NULL; |
1482 SECStatus rv = SECFailure; | 1482 SECStatus rv = SECFailure; |
1483 CERTOCSPRequest *dest = NULL; | 1483 CERTOCSPRequest *dest = NULL; |
1484 int i; | 1484 int i; |
1485 SECItem newSrc; | 1485 SECItem newSrc; |
1486 | 1486 |
1487 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1487 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
1488 if (arena == NULL) { | 1488 if (arena == NULL) { |
1489 goto loser; | 1489 goto loser; |
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2901 | 2901 |
2902 /* | 2902 /* |
2903 * Sends an encoded OCSP request to the server identified by "location", | 2903 * Sends an encoded OCSP request to the server identified by "location", |
2904 * and returns the socket on which it was sent (so can listen for the reply). | 2904 * and returns the socket on which it was sent (so can listen for the reply). |
2905 * "location" is expected to be a valid URL -- an error parsing it produces | 2905 * "location" is expected to be a valid URL -- an error parsing it produces |
2906 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems | 2906 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems |
2907 * connecting to it, or writing to it, or allocating memory, and the low-level | 2907 * connecting to it, or writing to it, or allocating memory, and the low-level |
2908 * errors appropriate to the problem will be set. | 2908 * errors appropriate to the problem will be set. |
2909 */ | 2909 */ |
2910 static PRFileDesc * | 2910 static PRFileDesc * |
2911 ocsp_SendEncodedRequest(char *location, SECItem *encodedRequest) | 2911 ocsp_SendEncodedRequest(const char *location, SECItem *encodedRequest) |
2912 { | 2912 { |
2913 char *hostname = NULL; | 2913 char *hostname = NULL; |
2914 char *path = NULL; | 2914 char *path = NULL; |
2915 PRUint16 port; | 2915 PRUint16 port; |
2916 SECStatus rv; | 2916 SECStatus rv; |
2917 PRFileDesc *sock = NULL; | 2917 PRFileDesc *sock = NULL; |
2918 PRFileDesc *returnSock = NULL; | 2918 PRFileDesc *returnSock = NULL; |
2919 char *header = NULL; | 2919 char *header = NULL; |
2920 char portstr[16]; | 2920 char portstr[16]; |
2921 | 2921 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3260 } | 3260 } |
3261 | 3261 |
3262 /* | 3262 /* |
3263 * Limit the size of http responses we are willing to accept. | 3263 * Limit the size of http responses we are willing to accept. |
3264 */ | 3264 */ |
3265 #define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024 | 3265 #define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024 |
3266 | 3266 |
3267 static SECItem * | 3267 static SECItem * |
3268 fetchOcspHttpClientV1(PRArenaPool *arena, | 3268 fetchOcspHttpClientV1(PRArenaPool *arena, |
3269 const SEC_HttpClientFcnV1 *hcv1, | 3269 const SEC_HttpClientFcnV1 *hcv1, |
3270 char *location, | 3270 const char *location, |
3271 SECItem *encodedRequest) | 3271 SECItem *encodedRequest) |
3272 { | 3272 { |
3273 char *hostname = NULL; | 3273 char *hostname = NULL; |
3274 char *path = NULL; | 3274 char *path = NULL; |
3275 PRUint16 port; | 3275 PRUint16 port; |
3276 SECItem *encodedResponse = NULL; | 3276 SECItem *encodedResponse = NULL; |
3277 SEC_HTTP_SERVER_SESSION pServerSession = NULL; | 3277 SEC_HTTP_SERVER_SESSION pServerSession = NULL; |
3278 SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; | 3278 SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; |
3279 PRUint16 myHttpResponseCode; | 3279 PRUint16 myHttpResponseCode; |
3280 const char *myHttpResponseData; | 3280 const char *myHttpResponseData; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3379 * If NULL, result will be allocated from the heap (and thus should | 3379 * If NULL, result will be allocated from the heap (and thus should |
3380 * be freed via SECITEM_FreeItem). | 3380 * be freed via SECITEM_FreeItem). |
3381 * CERTCertList *certList | 3381 * CERTCertList *certList |
3382 * A list of certs for which status will be requested. | 3382 * A list of certs for which status will be requested. |
3383 * Note that all of these certificates should have the same issuer, | 3383 * Note that all of these certificates should have the same issuer, |
3384 * or it's expected the response will be signed by a trusted responder. | 3384 * or it's expected the response will be signed by a trusted responder. |
3385 * If the certs need to be broken up into multiple requests, that | 3385 * If the certs need to be broken up into multiple requests, that |
3386 * must be handled by the caller (and thus by having multiple calls | 3386 * must be handled by the caller (and thus by having multiple calls |
3387 * to this routine), who knows about where the request(s) are being | 3387 * to this routine), who knows about where the request(s) are being |
3388 * sent and whether there are any trusted responders in place. | 3388 * sent and whether there are any trusted responders in place. |
3389 * char *location | 3389 * const char *location |
3390 * The location of the OCSP responder (a URL). | 3390 * The location of the OCSP responder (a URL). |
3391 * int64 time | 3391 * int64 time |
3392 * Indicates the time for which the certificate status is to be | 3392 * Indicates the time for which the certificate status is to be |
3393 * determined -- this may be used in the search for the cert's issuer | 3393 * determined -- this may be used in the search for the cert's issuer |
3394 * but has no other bearing on the operation. | 3394 * but has no other bearing on the operation. |
3395 * PRBool addServiceLocator | 3395 * PRBool addServiceLocator |
3396 * If true, the Service Locator extension should be added to the | 3396 * If true, the Service Locator extension should be added to the |
3397 * single request(s) for each cert. | 3397 * single request(s) for each cert. |
3398 * CERTCertificate *signerCert | 3398 * CERTCertificate *signerCert |
3399 * If non-NULL, means sign the request using this cert. Otherwise, | 3399 * If non-NULL, means sign the request using this cert. Otherwise, |
(...skipping 10 matching lines...) Expand all Loading... |
3410 * RETURN: | 3410 * RETURN: |
3411 * Returns a pointer to the SECItem holding the response. | 3411 * Returns a pointer to the SECItem holding the response. |
3412 * On error, returns null with error set describing the reason: | 3412 * On error, returns null with error set describing the reason: |
3413 * SEC_ERROR_UNKNOWN_ISSUER | 3413 * SEC_ERROR_UNKNOWN_ISSUER |
3414 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION | 3414 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION |
3415 * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE | 3415 * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE |
3416 * Other errors are low-level problems (no memory, bad database, etc.). | 3416 * Other errors are low-level problems (no memory, bad database, etc.). |
3417 */ | 3417 */ |
3418 SECItem * | 3418 SECItem * |
3419 CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, | 3419 CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, |
3420 » » » char *location, int64 time, | 3420 » » » const char *location, int64 time, |
3421 PRBool addServiceLocator, | 3421 PRBool addServiceLocator, |
3422 CERTCertificate *signerCert, void *pwArg, | 3422 CERTCertificate *signerCert, void *pwArg, |
3423 CERTOCSPRequest **pRequest) | 3423 CERTOCSPRequest **pRequest) |
3424 { | 3424 { |
3425 CERTOCSPRequest *request; | 3425 CERTOCSPRequest *request; |
3426 request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, | 3426 request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, |
3427 signerCert); | 3427 signerCert); |
3428 if (!request) | 3428 if (!request) |
3429 return NULL; | 3429 return NULL; |
3430 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, | 3430 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, |
3431 time, addServiceLocator, | 3431 time, addServiceLocator, |
3432 pwArg, pRequest); | 3432 pwArg, pRequest); |
3433 } | 3433 } |
3434 | 3434 |
3435 static SECItem * | 3435 static SECItem * |
3436 ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena, | 3436 ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena, |
3437 CERTOCSPRequest *request, | 3437 CERTOCSPRequest *request, |
3438 char *location, int64 time, | 3438 const char *location, int64 time, |
3439 PRBool addServiceLocator, | 3439 PRBool addServiceLocator, |
3440 void *pwArg, | 3440 void *pwArg, |
3441 CERTOCSPRequest **pRequest) | 3441 CERTOCSPRequest **pRequest) |
3442 { | 3442 { |
3443 SECItem *encodedRequest = NULL; | 3443 SECItem *encodedRequest = NULL; |
3444 SECItem *encodedResponse = NULL; | 3444 SECItem *encodedResponse = NULL; |
3445 PRFileDesc *sock = NULL; | 3445 PRFileDesc *sock = NULL; |
3446 SECStatus rv; | 3446 SECStatus rv; |
3447 const SEC_HttpClientFcn *registeredHttpClient = NULL; | 3447 const SEC_HttpClientFcn *registeredHttpClient = NULL; |
3448 | 3448 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 if (sock != NULL) | 3489 if (sock != NULL) |
3490 PR_Close(sock); | 3490 PR_Close(sock); |
3491 | 3491 |
3492 return encodedResponse; | 3492 return encodedResponse; |
3493 } | 3493 } |
3494 | 3494 |
3495 static SECItem * | 3495 static SECItem * |
3496 ocsp_GetEncodedOCSPResponseForSingleCert(PRArenaPool *arena, | 3496 ocsp_GetEncodedOCSPResponseForSingleCert(PRArenaPool *arena, |
3497 CERTOCSPCertID *certID, | 3497 CERTOCSPCertID *certID, |
3498 CERTCertificate *singleCert, | 3498 CERTCertificate *singleCert, |
3499 char *location, int64 time, | 3499 const char *location, int64 time, |
3500 PRBool addServiceLocator, | 3500 PRBool addServiceLocator, |
3501 void *pwArg, | 3501 void *pwArg, |
3502 CERTOCSPRequest **pRequest) | 3502 CERTOCSPRequest **pRequest) |
3503 { | 3503 { |
3504 CERTOCSPRequest *request; | 3504 CERTOCSPRequest *request; |
3505 request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time, | 3505 request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time, |
3506 addServiceLocator, NULL); | 3506 addServiceLocator, NULL); |
3507 if (!request) | 3507 if (!request) |
3508 return NULL; | 3508 return NULL; |
3509 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, | 3509 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, |
(...skipping 2182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5692 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); | 5692 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); |
5693 break; | 5693 break; |
5694 case ocspResponse_other: | 5694 case ocspResponse_other: |
5695 case ocspResponse_unused: | 5695 case ocspResponse_unused: |
5696 default: | 5696 default: |
5697 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS); | 5697 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS); |
5698 break; | 5698 break; |
5699 } | 5699 } |
5700 return SECFailure; | 5700 return SECFailure; |
5701 } | 5701 } |
OLD | NEW |