diff options
Diffstat (limited to 'crypto/ocsp')
-rw-r--r-- | crypto/ocsp/ocsp.h | 10 | ||||
-rw-r--r-- | crypto/ocsp/ocsp_cl.c | 72 | ||||
-rw-r--r-- | crypto/ocsp/ocsp_err.c | 7 |
3 files changed, 87 insertions, 2 deletions
diff --git a/crypto/ocsp/ocsp.h b/crypto/ocsp/ocsp.h index 18249abc38..bccdf77b4f 100644 --- a/crypto/ocsp/ocsp.h +++ b/crypto/ocsp/ocsp.h @@ -444,6 +444,9 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, + long sec, long maxsec); int OCSP_request_verify(OCSP_REQUEST *req, EVP_PKEY *pkey); @@ -569,6 +572,7 @@ void ERR_load_OCSP_strings(void); #define OCSP_F_OCSP_CHECK_DELEGATED 106 #define OCSP_F_OCSP_CHECK_IDS 107 #define OCSP_F_OCSP_CHECK_ISSUER 108 +#define OCSP_F_OCSP_CHECK_VALIDITY 115 #define OCSP_F_OCSP_MATCH_ISSUERID 109 #define OCSP_F_OCSP_PARSE_URL 114 #define OCSP_F_OCSP_REQUEST_SIGN 110 @@ -580,8 +584,11 @@ void ERR_load_OCSP_strings(void); #define OCSP_R_BAD_DATA 100 #define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 #define OCSP_R_DIGEST_ERR 102 +#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +#define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 #define OCSP_R_ERROR_PARSING_URL 121 #define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 #define OCSP_R_NOT_BASIC_RESPONSE 104 #define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 #define OCSP_R_NO_CONTENT 106 @@ -597,6 +604,9 @@ void ERR_load_OCSP_strings(void); #define OCSP_R_SERVER_WRITE_ERROR 116 #define OCSP_R_SIGNATURE_FAILURE 117 #define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +#define OCSP_R_STATUS_EXPIRED 125 +#define OCSP_R_STATUS_NOT_YET_VALID 126 +#define OCSP_R_STATUS_TOO_OLD 127 #define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 #define OCSP_R_UNKNOWN_NID 120 diff --git a/crypto/ocsp/ocsp_cl.c b/crypto/ocsp/ocsp_cl.c index 909525210f..9b3e6dd8ca 100644 --- a/crypto/ocsp/ocsp_cl.c +++ b/crypto/ocsp/ocsp_cl.c @@ -62,6 +62,7 @@ */ #include <stdio.h> +#include <time.h> #include <cryptlib.h> #include <openssl/objects.h> #include <openssl/rand.h> @@ -259,8 +260,9 @@ int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, ASN1_GENERALIZEDTIME **nextupd) { int ret; - OCSP_CERTSTATUS *cst = single->certStatus; + OCSP_CERTSTATUS *cst; if(!single) return -1; + cst = single->certStatus; ret = cst->type; if (ret == V_OCSP_CERTSTATUS_REVOKED) { @@ -278,7 +280,7 @@ int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, return ret; } -/* This function combines the previous ones: look a certificate ID and +/* This function combines the previous ones: look up a certificate ID and * if found extract status information. Return 0 is successful. */ @@ -299,4 +301,70 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, return 1; } +/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will + * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid + * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time. + * Also to avoid accepting very old responses without a nextUpdate field an optional maxage + * parameter specifies the maximum age the thisUpdate field can be. + */ + +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) + { + int ret = 1; + time_t t_now, t_tmp; + time(&t_now); + /* Check thisUpdate is valid and not more than nsec in the future */ + if (!ASN1_GENERALIZEDTIME_check(thisupd)) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); + ret = 0; + } + else + { + t_tmp = t_now + nsec; + if (X509_cmp_time(thisupd, &t_tmp) > 0) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); + ret = 0; + } + + /* If maxsec specified check thisUpdate is not more than maxsec in the past */ + if (maxsec >= 0) + { + t_tmp = t_now - maxsec; + if (X509_cmp_time(thisupd, &t_tmp) < 0) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); + ret = 0; + } + } + } + + + if (!nextupd) return ret; + /* Check nextUpdate is valid and not more than nsec in the past */ + if (!ASN1_GENERALIZEDTIME_check(nextupd)) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); + ret = 0; + } + else + { + t_tmp = t_now - nsec; + if (X509_cmp_time(nextupd, &t_tmp) < 0) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); + ret = 0; + } + } + + /* Also don't allow nextUpdate to precede thisUpdate */ + if (ASN1_STRING_cmp(nextupd, thisupd) < 0) + { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); + ret = 0; + } + + return ret; + } diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c index 79107190e5..1cbf9cab30 100644 --- a/crypto/ocsp/ocsp_err.c +++ b/crypto/ocsp/ocsp_err.c @@ -75,6 +75,7 @@ static ERR_STRING_DATA OCSP_str_functs[]= {ERR_PACK(0,OCSP_F_OCSP_CHECK_DELEGATED,0), "OCSP_CHECK_DELEGATED"}, {ERR_PACK(0,OCSP_F_OCSP_CHECK_IDS,0), "OCSP_CHECK_IDS"}, {ERR_PACK(0,OCSP_F_OCSP_CHECK_ISSUER,0), "OCSP_CHECK_ISSUER"}, +{ERR_PACK(0,OCSP_F_OCSP_CHECK_VALIDITY,0), "OCSP_check_validity"}, {ERR_PACK(0,OCSP_F_OCSP_MATCH_ISSUERID,0), "OCSP_MATCH_ISSUERID"}, {ERR_PACK(0,OCSP_F_OCSP_PARSE_URL,0), "OCSP_parse_url"}, {ERR_PACK(0,OCSP_F_OCSP_REQUEST_SIGN,0), "OCSP_request_sign"}, @@ -89,8 +90,11 @@ static ERR_STRING_DATA OCSP_str_reasons[]= {OCSP_R_BAD_DATA ,"bad data"}, {OCSP_R_CERTIFICATE_VERIFY_ERROR ,"certificate verify error"}, {OCSP_R_DIGEST_ERR ,"digest err"}, +{OCSP_R_ERROR_IN_NEXTUPDATE_FIELD ,"error in nextupdate field"}, +{OCSP_R_ERROR_IN_THISUPDATE_FIELD ,"error in thisupdate field"}, {OCSP_R_ERROR_PARSING_URL ,"error parsing url"}, {OCSP_R_MISSING_OCSPSIGNING_USAGE ,"missing ocspsigning usage"}, +{OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE ,"nextupdate before thisupdate"}, {OCSP_R_NOT_BASIC_RESPONSE ,"not basic response"}, {OCSP_R_NO_CERTIFICATES_IN_CHAIN ,"no certificates in chain"}, {OCSP_R_NO_CONTENT ,"no content"}, @@ -106,6 +110,9 @@ static ERR_STRING_DATA OCSP_str_reasons[]= {OCSP_R_SERVER_WRITE_ERROR ,"server write error"}, {OCSP_R_SIGNATURE_FAILURE ,"signature failure"}, {OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND ,"signer certificate not found"}, +{OCSP_R_STATUS_EXPIRED ,"status expired"}, +{OCSP_R_STATUS_NOT_YET_VALID ,"status not yet valid"}, +{OCSP_R_STATUS_TOO_OLD ,"status too old"}, {OCSP_R_UNKNOWN_MESSAGE_DIGEST ,"unknown message digest"}, {OCSP_R_UNKNOWN_NID ,"unknown nid"}, {0,NULL} |