iPXE
ocsp.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  */
00019 
00020 FILE_LICENCE ( GPL2_OR_LATER );
00021 
00022 #include <stdint.h>
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <errno.h>
00027 #include <ipxe/asn1.h>
00028 #include <ipxe/x509.h>
00029 #include <ipxe/sha1.h>
00030 #include <ipxe/base64.h>
00031 #include <ipxe/uri.h>
00032 #include <ipxe/ocsp.h>
00033 #include <config/crypto.h>
00034 
00035 /** @file
00036  *
00037  * Online Certificate Status Protocol
00038  *
00039  */
00040 
00041 /* Disambiguate the various error causes */
00042 #define EACCES_CERT_STATUS                                              \
00043         __einfo_error ( EINFO_EACCES_CERT_STATUS )
00044 #define EINFO_EACCES_CERT_STATUS                                        \
00045         __einfo_uniqify ( EINFO_EACCES, 0x01,                           \
00046                           "Certificate status not good" )
00047 #define EACCES_CERT_MISMATCH                                            \
00048         __einfo_error ( EINFO_EACCES_CERT_MISMATCH )
00049 #define EINFO_EACCES_CERT_MISMATCH                                      \
00050         __einfo_uniqify ( EINFO_EACCES, 0x02,                           \
00051                           "Certificate ID mismatch" )
00052 #define EACCES_NON_OCSP_SIGNING                                         \
00053         __einfo_error ( EINFO_EACCES_NON_OCSP_SIGNING )
00054 #define EINFO_EACCES_NON_OCSP_SIGNING                                   \
00055         __einfo_uniqify ( EINFO_EACCES, 0x03,                           \
00056                           "Not an OCSP signing certificate" )
00057 #define EACCES_STALE                                                    \
00058         __einfo_error ( EINFO_EACCES_STALE )
00059 #define EINFO_EACCES_STALE                                              \
00060         __einfo_uniqify ( EINFO_EACCES, 0x04,                           \
00061                           "Stale (or premature) OCSP repsonse" )
00062 #define EACCES_NO_RESPONDER                                             \
00063         __einfo_error ( EINFO_EACCES_NO_RESPONDER )
00064 #define EINFO_EACCES_NO_RESPONDER                                       \
00065         __einfo_uniqify ( EINFO_EACCES, 0x05,                           \
00066                           "Missing OCSP responder certificate" )
00067 #define ENOTSUP_RESPONSE_TYPE                                           \
00068         __einfo_error ( EINFO_ENOTSUP_RESPONSE_TYPE )
00069 #define EINFO_ENOTSUP_RESPONSE_TYPE                                     \
00070         __einfo_uniqify ( EINFO_ENOTSUP, 0x01,                          \
00071                           "Unsupported OCSP response type" )
00072 #define ENOTSUP_RESPONDER_ID                                            \
00073         __einfo_error ( EINFO_ENOTSUP_RESPONDER_ID )
00074 #define EINFO_ENOTSUP_RESPONDER_ID                                      \
00075         __einfo_uniqify ( EINFO_ENOTSUP, 0x02,                          \
00076                           "Unsupported OCSP responder ID" )
00077 #define EPROTO_MALFORMED_REQUEST                                        \
00078         __einfo_error ( EINFO_EPROTO_MALFORMED_REQUEST )
00079 #define EINFO_EPROTO_MALFORMED_REQUEST                                  \
00080         __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_MALFORMED_REQUEST,  \
00081                           "Illegal confirmation request" )
00082 #define EPROTO_INTERNAL_ERROR                                           \
00083         __einfo_error ( EINFO_EPROTO_INTERNAL_ERROR )
00084 #define EINFO_EPROTO_INTERNAL_ERROR                                     \
00085         __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_INTERNAL_ERROR,     \
00086                           "Internal error in issuer" )
00087 #define EPROTO_TRY_LATER                                                \
00088         __einfo_error ( EINFO_EPROTO_TRY_LATER )
00089 #define EINFO_EPROTO_TRY_LATER                                          \
00090         __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_TRY_LATER,          \
00091                           "Try again later" )
00092 #define EPROTO_SIG_REQUIRED                                             \
00093         __einfo_error ( EINFO_EPROTO_SIG_REQUIRED )
00094 #define EINFO_EPROTO_SIG_REQUIRED                                       \
00095         __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_SIG_REQUIRED,       \
00096                           "Must sign the request" )
00097 #define EPROTO_UNAUTHORIZED                                             \
00098         __einfo_error ( EINFO_EPROTO_UNAUTHORIZED )
00099 #define EINFO_EPROTO_UNAUTHORIZED                                       \
00100         __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_UNAUTHORIZED,       \
00101                           "Request unauthorized" )
00102 #define EPROTO_STATUS( status )                                         \
00103         EUNIQ ( EINFO_EPROTO, (status), EPROTO_MALFORMED_REQUEST,       \
00104                 EPROTO_INTERNAL_ERROR, EPROTO_TRY_LATER,                \
00105                 EPROTO_SIG_REQUIRED, EPROTO_UNAUTHORIZED )
00106 
00107 /** OCSP digest algorithm */
00108 #define ocsp_digest_algorithm sha1_algorithm
00109 
00110 /** OCSP digest algorithm identifier */
00111 static const uint8_t ocsp_algorithm_id[] =
00112         { OCSP_ALGORITHM_IDENTIFIER ( ASN1_OID_SHA1 ) };
00113 
00114 /** OCSP basic response type */
00115 static const uint8_t oid_basic_response_type[] = { ASN1_OID_OCSP_BASIC };
00116 
00117 /** OCSP basic response type cursor */
00118 static struct asn1_cursor oid_basic_response_type_cursor =
00119         ASN1_OID_CURSOR ( oid_basic_response_type );
00120 
00121 /**
00122  * Free OCSP check
00123  *
00124  * @v refcnt            Reference count
00125  */
00126 static void ocsp_free ( struct refcnt *refcnt ) {
00127         struct ocsp_check *ocsp =
00128                 container_of ( refcnt, struct ocsp_check, refcnt );
00129 
00130         x509_put ( ocsp->cert );
00131         x509_put ( ocsp->issuer );
00132         free ( ocsp->uri_string );
00133         free ( ocsp->request.builder.data );
00134         free ( ocsp->response.data );
00135         x509_put ( ocsp->response.signer );
00136         free ( ocsp );
00137 }
00138 
00139 /**
00140  * Build OCSP request
00141  *
00142  * @v ocsp              OCSP check
00143  * @ret rc              Return status code
00144  */
00145 static int ocsp_request ( struct ocsp_check *ocsp ) {
00146         struct digest_algorithm *digest = &ocsp_digest_algorithm;
00147         struct asn1_builder *builder = &ocsp->request.builder;
00148         struct asn1_cursor *cert_id = &ocsp->request.cert_id;
00149         uint8_t digest_ctx[digest->ctxsize];
00150         uint8_t name_digest[digest->digestsize];
00151         uint8_t pubkey_digest[digest->digestsize];
00152         int rc;
00153 
00154         /* Generate digests */
00155         digest_init ( digest, digest_ctx );
00156         digest_update ( digest, digest_ctx, ocsp->cert->issuer.raw.data,
00157                         ocsp->cert->issuer.raw.len );
00158         digest_final ( digest, digest_ctx, name_digest );
00159         digest_init ( digest, digest_ctx );
00160         digest_update ( digest, digest_ctx,
00161                         ocsp->issuer->subject.public_key.raw_bits.data,
00162                         ocsp->issuer->subject.public_key.raw_bits.len );
00163         digest_final ( digest, digest_ctx, pubkey_digest );
00164 
00165         /* Construct request */
00166         if ( ( rc = ( asn1_prepend_raw ( builder, ocsp->cert->serial.raw.data,
00167                                          ocsp->cert->serial.raw.len ),
00168                       asn1_prepend ( builder, ASN1_OCTET_STRING,
00169                                      pubkey_digest, sizeof ( pubkey_digest ) ),
00170                       asn1_prepend ( builder, ASN1_OCTET_STRING,
00171                                      name_digest, sizeof ( name_digest ) ),
00172                       asn1_prepend ( builder, ASN1_SEQUENCE,
00173                                      ocsp_algorithm_id,
00174                                      sizeof ( ocsp_algorithm_id ) ),
00175                       asn1_wrap ( builder, ASN1_SEQUENCE ),
00176                       asn1_wrap ( builder, ASN1_SEQUENCE ),
00177                       asn1_wrap ( builder, ASN1_SEQUENCE ),
00178                       asn1_wrap ( builder, ASN1_SEQUENCE ),
00179                       asn1_wrap ( builder, ASN1_SEQUENCE ) ) ) != 0 ) {
00180                 DBGC ( ocsp, "OCSP %p \"%s\" could not build request: %s\n",
00181                        ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
00182                 return rc;
00183         }
00184         DBGC2 ( ocsp, "OCSP %p \"%s\" request is:\n",
00185                 ocsp, x509_name ( ocsp->cert ) );
00186         DBGC2_HDA ( ocsp, 0, builder->data, builder->len );
00187 
00188         /* Parse certificate ID for comparison with response */
00189         cert_id->data = builder->data;
00190         cert_id->len = builder->len;
00191         if ( ( rc = ( asn1_enter ( cert_id, ASN1_SEQUENCE ),
00192                       asn1_enter ( cert_id, ASN1_SEQUENCE ),
00193                       asn1_enter ( cert_id, ASN1_SEQUENCE ),
00194                       asn1_enter ( cert_id, ASN1_SEQUENCE ) ) ) != 0 ) {
00195                 DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
00196                        ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
00197                 return rc;
00198         }
00199 
00200         return 0;
00201 }
00202 
00203 /**
00204  * Build OCSP URI string
00205  *
00206  * @v ocsp              OCSP check
00207  * @ret rc              Return status code
00208  */
00209 static int ocsp_uri_string ( struct ocsp_check *ocsp ) {
00210         struct x509_ocsp_responder *responder =
00211                 &ocsp->cert->extensions.auth_info.ocsp;
00212         char *base64;
00213         char *sep;
00214         size_t base64_len;
00215         size_t uri_len;
00216         size_t len;
00217         int rc;
00218 
00219         /* Sanity check */
00220         if ( ! responder->uri.len ) {
00221                 DBGC ( ocsp, "OCSP %p \"%s\" has no OCSP URI\n",
00222                        ocsp, x509_name ( ocsp->cert ) );
00223                 rc = -ENOTTY;
00224                 goto err_no_uri;
00225         }
00226 
00227         /* Calculate base64-encoded request length */
00228         base64_len = ( base64_encoded_len ( ocsp->request.builder.len )
00229                        + 1 /* NUL */ );
00230 
00231         /* Allocate and construct the base64-encoded request */
00232         base64 = malloc ( base64_len );
00233         if ( ! base64 ) {
00234                 rc = -ENOMEM;
00235                 goto err_alloc_base64;
00236         }
00237         base64_encode ( ocsp->request.builder.data, ocsp->request.builder.len,
00238                         base64, base64_len );
00239 
00240         /* Calculate URI-encoded base64-encoded request length */
00241         uri_len = ( uri_encode ( URI_PATH, base64, ( base64_len - 1 /* NUL */ ),
00242                                  NULL, 0 ) + 1 /* NUL */ );
00243 
00244         /* Allocate and construct the URI string */
00245         len = ( responder->uri.len + 1 /* possible "/" */ + uri_len );
00246         ocsp->uri_string = zalloc ( len );
00247         if ( ! ocsp->uri_string ) {
00248                 rc = -ENOMEM;
00249                 goto err_alloc_uri;
00250         }
00251         memcpy ( ocsp->uri_string, responder->uri.data, responder->uri.len );
00252         sep = &ocsp->uri_string[ responder->uri.len - 1 ];
00253         if ( *sep != '/' )
00254                 *(++sep) = '/';
00255         uri_encode ( URI_PATH, base64, base64_len, ( sep + 1 ), uri_len );
00256         DBGC2 ( ocsp, "OCSP %p \"%s\" URI is %s\n",
00257                 ocsp, x509_name ( ocsp->cert ), ocsp->uri_string );
00258 
00259         /* Success */
00260         rc = 0;
00261 
00262  err_alloc_uri:
00263         free ( base64 );
00264  err_alloc_base64:
00265  err_no_uri:
00266         return rc;
00267 }
00268 
00269 /**
00270  * Create OCSP check
00271  *
00272  * @v cert              Certificate to check
00273  * @v issuer            Issuing certificate
00274  * @ret ocsp            OCSP check
00275  * @ret rc              Return status code
00276  */
00277 int ocsp_check ( struct x509_certificate *cert,
00278                  struct x509_certificate *issuer,
00279                  struct ocsp_check **ocsp ) {
00280         int rc;
00281 
00282         /* Sanity checks */
00283         assert ( cert != NULL );
00284         assert ( issuer != NULL );
00285         assert ( x509_is_valid ( issuer ) );
00286 
00287         /* Allocate and initialise check */
00288         *ocsp = zalloc ( sizeof ( **ocsp ) );
00289         if ( ! *ocsp ) {
00290                 rc = -ENOMEM;
00291                 goto err_alloc;
00292         }
00293         ref_init ( &(*ocsp)->refcnt, ocsp_free );
00294         (*ocsp)->cert = x509_get ( cert );
00295         (*ocsp)->issuer = x509_get ( issuer );
00296 
00297         /* Build request */
00298         if ( ( rc = ocsp_request ( *ocsp ) ) != 0 )
00299                 goto err_request;
00300 
00301         /* Build URI string */
00302         if ( ( rc = ocsp_uri_string ( *ocsp ) ) != 0 )
00303                 goto err_uri_string;
00304 
00305         return 0;
00306 
00307  err_uri_string:
00308  err_request:
00309         ocsp_put ( *ocsp );
00310  err_alloc:
00311         *ocsp = NULL;
00312         return rc;
00313 }
00314 
00315 /**
00316  * Parse OCSP response status
00317  *
00318  * @v ocsp              OCSP check
00319  * @v raw               ASN.1 cursor
00320  * @ret rc              Return status code
00321  */
00322 static int ocsp_parse_response_status ( struct ocsp_check *ocsp,
00323                                         const struct asn1_cursor *raw ) {
00324         struct asn1_cursor cursor;
00325         uint8_t status;
00326         int rc;
00327 
00328         /* Enter responseStatus */
00329         memcpy ( &cursor, raw, sizeof ( cursor ) );
00330         if ( ( rc = asn1_enter ( &cursor, ASN1_ENUMERATED ) ) != 0 ) {
00331                 DBGC ( ocsp, "OCSP %p \"%s\" could not locate responseStatus: "
00332                        "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
00333                 return rc;
00334         }
00335 
00336         /* Extract response status */
00337         if ( cursor.len != sizeof ( status ) ) {
00338                 DBGC ( ocsp, "OCSP %p \"%s\" invalid status:\n",
00339                        ocsp, x509_name ( ocsp->cert ) );
00340                 DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
00341                 return -EINVAL;
00342         }
00343         memcpy ( &status, cursor.data, sizeof ( status ) );
00344 
00345         /* Check response status */
00346         if ( status != OCSP_STATUS_SUCCESSFUL ) {
00347                 DBGC ( ocsp, "OCSP %p \"%s\" response status %d\n",
00348                        ocsp, x509_name ( ocsp->cert ), status );
00349                 return EPROTO_STATUS ( status );
00350         }
00351 
00352         return 0;
00353 }
00354 
00355 /**
00356  * Parse OCSP response type
00357  *
00358  * @v ocsp              OCSP check
00359  * @v raw               ASN.1 cursor
00360  * @ret rc              Return status code
00361  */
00362 static int ocsp_parse_response_type ( struct ocsp_check *ocsp,
00363                                       const struct asn1_cursor *raw ) {
00364         struct asn1_cursor cursor;
00365 
00366         /* Enter responseType */
00367         memcpy ( &cursor, raw, sizeof ( cursor ) );
00368         asn1_enter ( &cursor, ASN1_OID );
00369 
00370         /* Check responseType is "basic" */
00371         if ( asn1_compare ( &oid_basic_response_type_cursor, &cursor ) != 0 ) {
00372                 DBGC ( ocsp, "OCSP %p \"%s\" response type not supported:\n",
00373                        ocsp, x509_name ( ocsp->cert ) );
00374                 DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
00375                 return -ENOTSUP_RESPONSE_TYPE;
00376         }
00377 
00378         return 0;
00379 }
00380 
00381 /**
00382  * Compare responder's certificate name
00383  *
00384  * @v ocsp              OCSP check
00385  * @v cert              Certificate
00386  * @ret difference      Difference as returned by memcmp()
00387  */
00388 static int ocsp_compare_responder_name ( struct ocsp_check *ocsp,
00389                                          struct x509_certificate *cert ) {
00390         struct ocsp_responder *responder = &ocsp->response.responder;
00391 
00392         /* Compare responder ID with certificate's subject */
00393         return asn1_compare ( &responder->id, &cert->subject.raw );
00394 }
00395 
00396 /**
00397  * Compare responder's certificate public key hash
00398  *
00399  * @v ocsp              OCSP check
00400  * @v cert              Certificate
00401  * @ret difference      Difference as returned by memcmp()
00402  */
00403 static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp,
00404                                              struct x509_certificate *cert ) {
00405         struct ocsp_responder *responder = &ocsp->response.responder;
00406         struct asn1_cursor key_hash;
00407         uint8_t ctx[SHA1_CTX_SIZE];
00408         uint8_t digest[SHA1_DIGEST_SIZE];
00409         int difference;
00410 
00411         /* Enter responder key hash */
00412         memcpy ( &key_hash, &responder->id, sizeof ( key_hash ) );
00413         asn1_enter ( &key_hash, ASN1_OCTET_STRING );
00414 
00415         /* Sanity check */
00416         difference = ( sizeof ( digest ) - key_hash.len );
00417         if ( difference )
00418                 return difference;
00419 
00420         /* Generate SHA1 hash of certificate's public key */
00421         digest_init ( &sha1_algorithm, ctx );
00422         digest_update ( &sha1_algorithm, ctx,
00423                         cert->subject.public_key.raw_bits.data,
00424                         cert->subject.public_key.raw_bits.len );
00425         digest_final ( &sha1_algorithm, ctx, digest );
00426 
00427         /* Compare responder key hash with hash of certificate's public key */
00428         return memcmp ( digest, key_hash.data, sizeof ( digest ) );
00429 }
00430 
00431 /**
00432  * Parse OCSP responder ID
00433  *
00434  * @v ocsp              OCSP check
00435  * @v raw               ASN.1 cursor
00436  * @ret rc              Return status code
00437  */
00438 static int ocsp_parse_responder_id ( struct ocsp_check *ocsp,
00439                                      const struct asn1_cursor *raw ) {
00440         struct ocsp_responder *responder = &ocsp->response.responder;
00441         struct asn1_cursor *responder_id = &responder->id;
00442         unsigned int type;
00443 
00444         /* Enter responder ID */
00445         memcpy ( responder_id, raw, sizeof ( *responder_id ) );
00446         type = asn1_type ( responder_id );
00447         asn1_enter_any ( responder_id );
00448 
00449         /* Identify responder ID type */
00450         switch ( type ) {
00451         case ASN1_EXPLICIT_TAG ( 1 ) :
00452                 DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by name\n",
00453                         ocsp, x509_name ( ocsp->cert ) );
00454                 responder->compare = ocsp_compare_responder_name;
00455                 return 0;
00456         case ASN1_EXPLICIT_TAG ( 2 ) :
00457                 DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by key "
00458                         "hash\n", ocsp, x509_name ( ocsp->cert ) );
00459                 responder->compare = ocsp_compare_responder_key_hash;
00460                 return 0;
00461         default:
00462                 DBGC ( ocsp, "OCSP %p \"%s\" unsupported responder ID type "
00463                        "%d\n", ocsp, x509_name ( ocsp->cert ), type );
00464                 return -ENOTSUP_RESPONDER_ID;
00465         }
00466 }
00467 
00468 /**
00469  * Parse OCSP certificate ID
00470  *
00471  * @v ocsp              OCSP check
00472  * @v raw               ASN.1 cursor
00473  * @ret rc              Return status code
00474  */
00475 static int ocsp_parse_cert_id ( struct ocsp_check *ocsp,
00476                                 const struct asn1_cursor *raw ) {
00477         struct asn1_cursor cursor;
00478 
00479         /* Check certID matches request */
00480         memcpy ( &cursor, raw, sizeof ( cursor ) );
00481         asn1_shrink_any ( &cursor );
00482         if ( asn1_compare ( &cursor, &ocsp->request.cert_id ) != 0 ) {
00483                 DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
00484                        ocsp, x509_name ( ocsp->cert ) );
00485                 DBGC_HDA ( ocsp, 0, ocsp->request.cert_id.data,
00486                            ocsp->request.cert_id.len );
00487                 DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
00488                 return -EACCES_CERT_MISMATCH;
00489         }
00490 
00491         return 0;
00492 }
00493 
00494 /**
00495  * Parse OCSP responses
00496  *
00497  * @v ocsp              OCSP check
00498  * @v raw               ASN.1 cursor
00499  * @ret rc              Return status code
00500  */
00501 static int ocsp_parse_responses ( struct ocsp_check *ocsp,
00502                                   const struct asn1_cursor *raw ) {
00503         struct ocsp_response *response = &ocsp->response;
00504         struct asn1_cursor cursor;
00505         int rc;
00506 
00507         /* Enter responses */
00508         memcpy ( &cursor, raw, sizeof ( cursor ) );
00509         asn1_enter ( &cursor, ASN1_SEQUENCE );
00510 
00511         /* Enter first singleResponse */
00512         asn1_enter ( &cursor, ASN1_SEQUENCE );
00513 
00514         /* Parse certID */
00515         if ( ( rc = ocsp_parse_cert_id ( ocsp, &cursor ) ) != 0 )
00516                 return rc;
00517         asn1_skip_any ( &cursor );
00518 
00519         /* Check certStatus */
00520         if ( asn1_type ( &cursor ) != ASN1_IMPLICIT_TAG ( 0 ) ) {
00521                 DBGC ( ocsp, "OCSP %p \"%s\" non-good certStatus:\n",
00522                        ocsp, x509_name ( ocsp->cert ) );
00523                 DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
00524                 return -EACCES_CERT_STATUS;
00525         }
00526         asn1_skip_any ( &cursor );
00527 
00528         /* Parse thisUpdate */
00529         if ( ( rc = asn1_generalized_time ( &cursor,
00530                                             &response->this_update ) ) != 0 ) {
00531                 DBGC ( ocsp, "OCSP %p \"%s\" could not parse thisUpdate: %s\n",
00532                        ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
00533                 return rc;
00534         }
00535         DBGC2 ( ocsp, "OCSP %p \"%s\" this update was at time %lld\n",
00536                 ocsp, x509_name ( ocsp->cert ), response->this_update );
00537         asn1_skip_any ( &cursor );
00538 
00539         /* Parse nextUpdate, if present */
00540         if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
00541                 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
00542                 if ( ( rc = asn1_generalized_time ( &cursor,
00543                                              &response->next_update ) ) != 0 ) {
00544                         DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
00545                                "nextUpdate: %s\n", ocsp,
00546                                x509_name ( ocsp->cert ), strerror ( rc ) );
00547                         return rc;
00548                 }
00549                 DBGC2 ( ocsp, "OCSP %p \"%s\" next update is at time %lld\n",
00550                         ocsp, x509_name ( ocsp->cert ), response->next_update );
00551         } else {
00552                 /* If no nextUpdate is present, this indicates that
00553                  * "newer revocation information is available all the
00554                  * time".  Actually, this indicates that there is no
00555                  * point to performing the OCSP check, since an
00556                  * attacker could replay the response at any future
00557                  * time and it would still be valid.
00558                  */
00559                 DBGC ( ocsp, "OCSP %p \"%s\" responder is a moron\n",
00560                        ocsp, x509_name ( ocsp->cert ) );
00561                 response->next_update = time ( NULL );
00562         }
00563 
00564         return 0;
00565 }
00566 
00567 /**
00568  * Parse OCSP response data
00569  *
00570  * @v ocsp              OCSP check
00571  * @v raw               ASN.1 cursor
00572  * @ret rc              Return status code
00573  */
00574 static int ocsp_parse_tbs_response_data ( struct ocsp_check *ocsp,
00575                                           const struct asn1_cursor *raw ) {
00576         struct ocsp_response *response = &ocsp->response;
00577         struct asn1_cursor cursor;
00578         int rc;
00579 
00580         /* Record raw tbsResponseData */
00581         memcpy ( &cursor, raw, sizeof ( cursor ) );
00582         asn1_shrink_any ( &cursor );
00583         memcpy ( &response->tbs, &cursor, sizeof ( response->tbs ) );
00584 
00585         /* Enter tbsResponseData */
00586         asn1_enter ( &cursor, ASN1_SEQUENCE );
00587 
00588         /* Skip version, if present */
00589         asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
00590 
00591         /* Parse responderID */
00592         if ( ( rc = ocsp_parse_responder_id ( ocsp, &cursor ) ) != 0 )
00593                 return rc;
00594         asn1_skip_any ( &cursor );
00595 
00596         /* Skip producedAt */
00597         asn1_skip_any ( &cursor );
00598 
00599         /* Parse responses */
00600         if ( ( rc = ocsp_parse_responses ( ocsp, &cursor ) ) != 0 )
00601                 return rc;
00602 
00603         return 0;
00604 }
00605 
00606 /**
00607  * Parse OCSP certificates
00608  *
00609  * @v ocsp              OCSP check
00610  * @v raw               ASN.1 cursor
00611  * @ret rc              Return status code
00612  */
00613 static int ocsp_parse_certs ( struct ocsp_check *ocsp,
00614                               const struct asn1_cursor *raw ) {
00615         struct ocsp_response *response = &ocsp->response;
00616         struct asn1_cursor cursor;
00617         struct x509_certificate *cert;
00618         int rc;
00619 
00620         /* Enter certs */
00621         memcpy ( &cursor, raw, sizeof ( cursor ) );
00622         asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
00623         asn1_enter ( &cursor, ASN1_SEQUENCE );
00624 
00625         /* Parse certificate, if present.  The data structure permits
00626          * multiple certificates, but the protocol requires that the
00627          * OCSP signing certificate must either be the issuer itself,
00628          * or must be directly issued by the issuer (see RFC2560
00629          * section 4.2.2.2 "Authorized Responders").  We therefore
00630          * need to identify only the single certificate matching the
00631          * Responder ID.
00632          */
00633         while ( cursor.len ) {
00634 
00635                 /* Parse certificate */
00636                 if ( ( rc = x509_certificate ( cursor.data, cursor.len,
00637                                                &cert ) ) != 0 ) {
00638                         DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
00639                                "certificate: %s\n", ocsp,
00640                                x509_name ( ocsp->cert ), strerror ( rc ) );
00641                         DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
00642                         return rc;
00643                 }
00644 
00645                 /* Use if this certificate matches the responder ID */
00646                 if ( response->responder.compare ( ocsp, cert ) == 0 ) {
00647                         response->signer = cert;
00648                         DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by ",
00649                                 ocsp, x509_name ( ocsp->cert ) );
00650                         DBGC2 ( ocsp, "\"%s\"\n",
00651                                 x509_name ( response->signer ) );
00652                         return 0;
00653                 }
00654 
00655                 /* Otherwise, discard this certificate */
00656                 x509_put ( cert );
00657                 asn1_skip_any ( &cursor );
00658         }
00659 
00660         DBGC ( ocsp, "OCSP %p \"%s\" missing responder certificate\n",
00661                ocsp, x509_name ( ocsp->cert ) );
00662         return -EACCES_NO_RESPONDER;
00663 }
00664 
00665 /**
00666  * Parse OCSP basic response
00667  *
00668  * @v ocsp              OCSP check
00669  * @v raw               ASN.1 cursor
00670  * @ret rc              Return status code
00671  */
00672 static int ocsp_parse_basic_response ( struct ocsp_check *ocsp,
00673                                        const struct asn1_cursor *raw ) {
00674         struct ocsp_response *response = &ocsp->response;
00675         struct asn1_algorithm **algorithm = &response->algorithm;
00676         struct asn1_bit_string *signature = &response->signature;
00677         struct asn1_cursor cursor;
00678         int rc;
00679 
00680         /* Enter BasicOCSPResponse */
00681         memcpy ( &cursor, raw, sizeof ( cursor ) );
00682         asn1_enter ( &cursor, ASN1_SEQUENCE );
00683 
00684         /* Parse tbsResponseData */
00685         if ( ( rc = ocsp_parse_tbs_response_data ( ocsp, &cursor ) ) != 0 )
00686                 return rc;
00687         asn1_skip_any ( &cursor );
00688 
00689         /* Parse signatureAlgorithm */
00690         if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
00691                 DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature "
00692                        "algorithm: %s\n",
00693                        ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
00694                 return rc;
00695         }
00696         DBGC2 ( ocsp, "OCSP %p \"%s\" signature algorithm is %s\n",
00697                 ocsp, x509_name ( ocsp->cert ), (*algorithm)->name );
00698         asn1_skip_any ( &cursor );
00699 
00700         /* Parse signature */
00701         if ( ( rc = asn1_integral_bit_string ( &cursor, signature ) ) != 0 ) {
00702                 DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature: %s\n",
00703                        ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
00704                 return rc;
00705         }
00706         asn1_skip_any ( &cursor );
00707 
00708         /* Parse certs, if present */
00709         if ( ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) &&
00710              ( ( rc = ocsp_parse_certs ( ocsp, &cursor ) ) != 0 ) )
00711                 return rc;
00712 
00713         return 0;
00714 }
00715 
00716 /**
00717  * Parse OCSP response bytes
00718  *
00719  * @v ocsp              OCSP check
00720  * @v raw               ASN.1 cursor
00721  * @ret rc              Return status code
00722  */
00723 static int ocsp_parse_response_bytes ( struct ocsp_check *ocsp,
00724                                        const struct asn1_cursor *raw ) {
00725         struct asn1_cursor cursor;
00726         int rc;
00727 
00728         /* Enter responseBytes */
00729         memcpy ( &cursor, raw, sizeof ( cursor ) );
00730         asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
00731         asn1_enter ( &cursor, ASN1_SEQUENCE );
00732 
00733         /* Parse responseType */
00734         if ( ( rc = ocsp_parse_response_type ( ocsp, &cursor ) ) != 0 )
00735                 return rc;
00736         asn1_skip_any ( &cursor );
00737 
00738         /* Enter response */
00739         asn1_enter ( &cursor, ASN1_OCTET_STRING );
00740 
00741         /* Parse response */
00742         if ( ( rc = ocsp_parse_basic_response ( ocsp, &cursor ) ) != 0 )
00743                 return rc;
00744 
00745         return 0;
00746 }
00747 
00748 /**
00749  * Parse OCSP response
00750  *
00751  * @v ocsp              OCSP check
00752  * @v raw               ASN.1 cursor
00753  * @ret rc              Return status code
00754  */
00755 static int ocsp_parse_response ( struct ocsp_check *ocsp,
00756                                  const struct asn1_cursor *raw ) {
00757         struct asn1_cursor cursor;
00758         int rc;
00759 
00760         /* Enter OCSPResponse */
00761         memcpy ( &cursor, raw, sizeof ( cursor ) );
00762         asn1_enter ( &cursor, ASN1_SEQUENCE );
00763 
00764         /* Parse responseStatus */
00765         if ( ( rc = ocsp_parse_response_status ( ocsp, &cursor ) ) != 0 )
00766                 return rc;
00767         asn1_skip_any ( &cursor );
00768 
00769         /* Parse responseBytes */
00770         if ( ( rc = ocsp_parse_response_bytes ( ocsp, &cursor ) ) != 0 )
00771                 return rc;
00772 
00773         return 0;
00774 }
00775 
00776 /**
00777  * Receive OCSP response
00778  *
00779  * @v ocsp              OCSP check
00780  * @v data              Response data
00781  * @v len               Length of response data
00782  * @ret rc              Return status code
00783  */
00784 int ocsp_response ( struct ocsp_check *ocsp, const void *data, size_t len ) {
00785         struct ocsp_response *response = &ocsp->response;
00786         struct asn1_cursor cursor;
00787         int rc;
00788 
00789         /* Duplicate data */
00790         x509_put ( response->signer );
00791         response->signer = NULL;
00792         free ( response->data );
00793         response->data = malloc ( len );
00794         if ( ! response->data )
00795                 return -ENOMEM;
00796         memcpy ( response->data, data, len );
00797         cursor.data = response->data;
00798         cursor.len = len;
00799 
00800         /* Parse response */
00801         if ( ( rc = ocsp_parse_response ( ocsp, &cursor ) ) != 0 )
00802                 return rc;
00803 
00804         return 0;
00805 }
00806 
00807 /**
00808  * OCSP dummy root certificate store
00809  *
00810  * OCSP validation uses no root certificates, since it takes place
00811  * only when there already exists a validated issuer certificate.
00812  */
00813 static struct x509_root ocsp_root = {
00814         .digest = &ocsp_digest_algorithm,
00815         .count = 0,
00816         .fingerprints = NULL,
00817 };
00818 
00819 /**
00820  * Check OCSP response signature
00821  *
00822  * @v ocsp              OCSP check
00823  * @v signer            Signing certificate
00824  * @ret rc              Return status code
00825  */
00826 static int ocsp_check_signature ( struct ocsp_check *ocsp,
00827                                   struct x509_certificate *signer ) {
00828         struct ocsp_response *response = &ocsp->response;
00829         struct digest_algorithm *digest = response->algorithm->digest;
00830         struct pubkey_algorithm *pubkey = response->algorithm->pubkey;
00831         struct x509_public_key *public_key = &signer->subject.public_key;
00832         uint8_t digest_ctx[ digest->ctxsize ];
00833         uint8_t digest_out[ digest->digestsize ];
00834         uint8_t pubkey_ctx[ pubkey->ctxsize ];
00835         int rc;
00836 
00837         /* Generate digest */
00838         digest_init ( digest, digest_ctx );
00839         digest_update ( digest, digest_ctx, response->tbs.data,
00840                         response->tbs.len );
00841         digest_final ( digest, digest_ctx, digest_out );
00842 
00843         /* Initialise public-key algorithm */
00844         if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
00845                                   public_key->raw.len ) ) != 0 ) {
00846                 DBGC ( ocsp, "OCSP %p \"%s\" could not initialise public key: "
00847                        "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
00848                 goto err_init;
00849         }
00850 
00851         /* Verify digest */
00852         if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
00853                                     response->signature.data,
00854                                     response->signature.len ) ) != 0 ) {
00855                 DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
00856                        "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
00857                 goto err_verify;
00858         }
00859 
00860         DBGC2 ( ocsp, "OCSP %p \"%s\" signature is correct\n",
00861                 ocsp, x509_name ( ocsp->cert ) );
00862 
00863  err_verify:
00864         pubkey_final ( pubkey, pubkey_ctx );
00865  err_init:
00866         return rc;
00867 }
00868 
00869 /**
00870  * Validate OCSP response
00871  *
00872  * @v ocsp              OCSP check
00873  * @v time              Time at which to validate response
00874  * @ret rc              Return status code
00875  */
00876 int ocsp_validate ( struct ocsp_check *ocsp, time_t time ) {
00877         struct ocsp_response *response = &ocsp->response;
00878         struct x509_certificate *signer;
00879         int rc;
00880 
00881         /* Sanity checks */
00882         assert ( response->data != NULL );
00883 
00884         /* The response may include a signer certificate; if this is
00885          * not present then the response must have been signed
00886          * directly by the issuer.
00887          */
00888         signer = ( response->signer ? response->signer : ocsp->issuer );
00889 
00890         /* Validate signer, if applicable.  If the signer is not the
00891          * issuer, then it must be signed directly by the issuer.
00892          */
00893         if ( signer != ocsp->issuer ) {
00894                 /* Forcibly invalidate the signer, since we need to
00895                  * ensure that it was signed by our issuer (and not
00896                  * some other issuer).  This prevents a sub-CA's OCSP
00897                  * certificate from fraudulently signing OCSP
00898                  * responses from the parent CA.
00899                  */
00900                 x509_invalidate ( signer );
00901                 if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
00902                                             &ocsp_root ) ) != 0 ) {
00903                         DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
00904                                ocsp, x509_name ( ocsp->cert ) );
00905                         DBGC ( ocsp, "signer \"%s\": %s\n",
00906                                x509_name ( signer ), strerror ( rc ) );
00907                         return rc;
00908                 }
00909 
00910                 /* If signer is not the issuer, then it must have the
00911                  * extendedKeyUsage id-kp-OCSPSigning.
00912                  */
00913                 if ( ! ( signer->extensions.ext_usage.bits &
00914                          X509_OCSP_SIGNING ) ) {
00915                         DBGC ( ocsp, "OCSP %p \"%s\" ",
00916                                ocsp, x509_name ( ocsp->cert ) );
00917                         DBGC ( ocsp, "signer \"%s\" is not an OCSP-signing "
00918                                "certificate\n", x509_name ( signer ) );
00919                         return -EACCES_NON_OCSP_SIGNING;
00920                 }
00921         }
00922 
00923         /* Check OCSP response signature */
00924         if ( ( rc = ocsp_check_signature ( ocsp, signer ) ) != 0 )
00925                 return rc;
00926 
00927         /* Check OCSP response is valid at the specified time
00928          * (allowing for some margin of error).
00929          */
00930         if ( response->this_update > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
00931                 DBGC ( ocsp, "OCSP %p \"%s\" response is not yet valid (at "
00932                        "time %lld)\n", ocsp, x509_name ( ocsp->cert ), time );
00933                 return -EACCES_STALE;
00934         }
00935         if ( response->next_update < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
00936                 DBGC ( ocsp, "OCSP %p \"%s\" response is stale (at time "
00937                        "%lld)\n", ocsp, x509_name ( ocsp->cert ), time );
00938                 return -EACCES_STALE;
00939         }
00940         DBGC2 ( ocsp, "OCSP %p \"%s\" response is valid (at time %lld)\n",
00941                 ocsp, x509_name ( ocsp->cert ), time );
00942 
00943         /* Mark certificate as passing OCSP verification */
00944         ocsp->cert->extensions.auth_info.ocsp.good = 1;
00945 
00946         /* Validate certificate against issuer */
00947         if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
00948                                     &ocsp_root ) ) != 0 ) {
00949                 DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
00950                        "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
00951                 return rc;
00952         }
00953         DBGC ( ocsp, "OCSP %p \"%s\" successfully validated ",
00954                ocsp, x509_name ( ocsp->cert ) );
00955         DBGC ( ocsp, "using \"%s\"\n", x509_name ( signer ) );
00956 
00957         return 0;
00958 }