Kaidul

dffd

Dec 23rd, 2014
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.18 KB | None | 0 0
  1. #include <openssl/ocsp.h>
  2. #include <openssl/ssl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <openssl/evp.h>
  7. #include <openssl/x509.h>
  8.  
  9. typedef int (*spc_x509verifycallback_t)(int, X509_STORE_CTX *);
  10.  
  11. typedef struct {
  12.     char                      *cafile;
  13.     char                      *capath;
  14.     char                      *crlfile;
  15.     spc_x509verifycallback_t  callback;
  16.     STACK_OF(X509)            *certs;
  17.     STACK_OF(X509_CRL)        *crls;
  18.     char                      *use_certfile;
  19.     STACK_OF(X509)            *use_certs;
  20.     char                      *use_keyfile;
  21.     EVP_PKEY                  *use_key;
  22.     int                       flags;
  23. } spc_x509store_t;
  24.  
  25. typedef struct {
  26.     char            *url;
  27.     X509            *cert;
  28.     X509            *issuer;
  29.     spc_x509store_t *store;
  30.     X509            *sign_cert;
  31.     EVP_PKEY        *sign_key;
  32.     long            skew;
  33.     long            maxage;
  34. } spc_ocsprequest_t;
  35.  
  36. typedef enum {
  37.     SPC_OCSPRESULT_ERROR_INVALIDRESPONSE   = -12,
  38.     SPC_OCSPRESULT_ERROR_CONNECTFAILURE    = -11,
  39.     SPC_OCSPRESULT_ERROR_SIGNFAILURE       = -10,
  40.     SPC_OCSPRESULT_ERROR_BADOCSPADDRESS    = -9,
  41.     SPC_OCSPRESULT_ERROR_OUTOFMEMORY       = -8,
  42.     SPC_OCSPRESULT_ERROR_UNKNOWN           = -7,
  43.     SPC_OCSPRESULT_ERROR_UNAUTHORIZED      = -6,
  44.     SPC_OCSPRESULT_ERROR_SIGREQUIRED       = -5,
  45.     SPC_OCSPRESULT_ERROR_TRYLATER          = -3,
  46.     SPC_OCSPRESULT_ERROR_INTERNALERROR     = -2,
  47.     SPC_OCSPRESULT_ERROR_MALFORMEDREQUEST  = -1,
  48.     SPC_OCSPRESULT_CERTIFICATE_VALID       = 0,
  49.     SPC_OCSPRESULT_CERTIFICATE_REVOKED     = 1
  50. } spc_ocspresult_t;
  51.  
  52. spc_ocspresult_t spc_verify_via_ocsp(spc_ocsprequest_t *data) {
  53.     BIO                   *bio = 0;
  54.     int                   rc, reason, ssl, status;
  55.     char                  *host = 0, *path = 0, *port = 0;
  56.     SSL_CTX               *ctx = 0;
  57.     X509_STORE            *store = 0;
  58.     OCSP_CERTID           *id;
  59.     OCSP_REQUEST          *req = 0;
  60.     OCSP_RESPONSE         *resp = 0;
  61.     OCSP_BASICRESP        *basic = 0;
  62.     spc_ocspresult_t      result;
  63.     ASN1_GENERALIZEDTIME  *producedAt, *thisUpdate, *nextUpdate;
  64.    
  65.     result = SPC_OCSPRESULT_ERROR_UNKNOWN;
  66.     if (!OCSP_parse_url(data->url, &host, &port, &path, &ssl)) {
  67.         result = SPC_OCSPRESULT_ERROR_BADOCSPADDRESS;
  68.         goto end;
  69.     }
  70.     if (!(req = OCSP_REQUEST_new(  ))) {
  71.         result = SPC_OCSPRESULT_ERROR_OUTOFMEMORY;
  72.         goto end;
  73.     }
  74.    
  75.     id = OCSP_cert_to_id(0, data->cert, data->issuer);
  76.     if (!id || !OCSP_request_add0_id(req, id)) goto end;
  77.     OCSP_request_add1_nonce(req, 0, -1);
  78.    
  79.     /* sign the request */
  80.     if (data->sign_cert && data->sign_key &&
  81.         !OCSP_request_sign(req, data->sign_cert, data->sign_key, EVP_sha1(  ), 0, 0)) {
  82.         result = SPC_OCSPRESULT_ERROR_SIGNFAILURE;
  83.         goto end;
  84.     }
  85.    
  86.     /* establish a connection to the OCSP responder */
  87.     if (!(bio = spc_connect(host, atoi(port), ssl, data->store, &ctx))) {
  88.         result = SPC_OCSPRESULT_ERROR_CONNECTFAILURE;
  89.         goto end;
  90.     }
  91.    
  92.     /* send the request and get a response */
  93.     resp = OCSP_sendreq_bio(bio, path, req);
  94.     if ((rc = OCSP_response_status(resp)) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
  95.         switch (rc) {
  96.             case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
  97.                 result = SPC_OCSPRESULT_ERROR_MALFORMEDREQUEST; break;
  98.             case OCSP_RESPONSE_STATUS_INTERNALERROR:
  99.                 result = SPC_OCSPRESULT_ERROR_INTERNALERROR;    break;
  100.             case OCSP_RESPONSE_STATUS_TRYLATER:
  101.                 result = SPC_OCSPRESULT_ERROR_TRYLATER;         break;
  102.             case OCSP_RESPONSE_STATUS_SIGREQUIRED:
  103.                 result = SPC_OCSPRESULT_ERROR_SIGREQUIRED;      break;
  104.             case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
  105.                 result = SPC_OCSPRESULT_ERROR_UNAUTHORIZED;     break;
  106.         }
  107.         goto end;
  108.     }
  109.    
  110.     /* verify the response */
  111.     result = SPC_OCSPRESULT_ERROR_INVALIDRESPONSE;
  112.     if (!(basic = OCSP_response_get1_basic(resp))) goto end;
  113.     if (OCSP_check_nonce(req, basic) <= 0) goto end;
  114.     if (data->store && !(store = spc_create_x509store(data->store))) goto end;
  115.     if ((rc = OCSP_basic_verify(basic, 0, store, 0)) <= 0) goto end;
  116.    
  117.     if (!OCSP_resp_find_status(basic, id, &status, &reason, &producedAt,
  118.                                &thisUpdate, &nextUpdate))
  119.         goto end;
  120.     if (!OCSP_check_validity(thisUpdate, nextUpdate, data->skew, data->maxage))
  121.         goto end;
  122.    
  123.     /* All done.  Set the return code based on the status from the response. */
  124.     if (status == V_OCSP_CERTSTATUS_REVOKED)
  125.         result = SPC_OCSPRESULT_CERTIFICATE_REVOKED;
  126.     else
  127.         result = SPC_OCSPRESULT_CERTIFICATE_VALID;
  128.    
  129. end:
  130.     if (bio) BIO_free_all(bio);
  131.     if (host) OPENSSL_free(host);
  132.     if (port) OPENSSL_free(port);
  133.     if (path) OPENSSL_free(path);
  134.     if (req) OCSP_REQUEST_free(req);
  135.     if (resp) OCSP_RESPONSE_free(resp);
  136.     if (basic) OCSP_BASICRESP_free(basic);
  137.     if (ctx) SSL_CTX_free(ctx);
  138.     if (store) X509_STORE_free(store);
  139.     return result;
  140. }
  141.  
  142. int main() {
  143.     exit(0);
  144. }
Advertisement
Add Comment
Please, Sign In to add comment