22 #include "../../ADoc.h"
23 #include "../../log.h"
24 #include "../../Conf.h"
25 #include "../OpenSSLHelpers.h"
27 #include <openssl/err.h>
28 #include <openssl/pkcs12.h>
31 #include <Security/Security.h>
35 #if OPENSSL_VERSION_NUMBER > 0x10000000
45 static int password_callback(
char *
buf,
int bufsiz,
int,
void *)
47 static const char password[] =
"pass";
48 int res = strlen(password);
51 memcpy(buf, password, res);
76 BIO_free_all(connection);
79 EVP_PKEY_free(signKey);
92 char *_host = NULL, *_port = NULL, *_path = NULL;
94 if(!OCSP_parse_url(const_cast<char*>(url.c_str()), &_host, &_port, &_path, &sslFlag))
97 connhost = _host ? _host :
"";
98 connport = _port ? _port :
"";
109 if(!connport.empty())
110 host +=
":" + connport;
125 this->ocspCerts = ocspCerts;
139 this->certStore = certStore;
151 this->signCert = signCert;
152 this->signKey = signKey;
170 this->maxAge = maxAge;
193 OCSP_REQUEST* req = NULL; OCSP_REQUEST_scope reqScope(&req);
194 OCSP_RESPONSE* resp = NULL; OCSP_RESPONSE_scope respScope(&resp);
197 return checkCert(cert, issuer, nonce, &req, &resp);
221 const std::vector<unsigned char>& nonce, std::vector<unsigned char>& ocspResponseDER,
224 OCSP_REQUEST* req = NULL; OCSP_REQUEST_scope reqScope(&req);
225 OCSP_RESPONSE* resp = NULL; OCSP_RESPONSE_scope respScope(&resp);
228 CertStatus certStatus = checkCert(cert, issuer, nonce, &req, &resp);
232 int bufSize = i2d_OCSP_RESPONSE(resp, NULL);
238 ocspResponseDER.resize(bufSize);
239 unsigned char* pBuf = &ocspResponseDER[0];
240 bufSize = i2d_OCSP_RESPONSE(resp, &pBuf);
247 OCSP_BASICRESP* basic = OCSP_response_get1_basic(resp); OCSP_BASICRESP_scope basicScope(&basic);
248 producedAt = convert(basic->tbsResponseData->producedAt);
272 const std::vector<unsigned char>& nonce, OCSP_REQUEST** req, OCSP_RESPONSE** resp)
277 THROW_IOEXCEPTION(
"Can not check X.509 certificate, certificate is NULL pointer.");
281 THROW_IOEXCEPTION(
"Can not check X.509 certificate, issuer certificate is NULL pointer.");
291 SecIdentityRef identity = 0;
292 OSStatus err = SecIdentityCopyPreference(CFSTR(
"ocsp.sk.ee"), 0, 0, &identity);
296 SecCertificateRef certref = 0;
297 SecKeyRef keyref = 0;
298 err = SecIdentityCopyCertificate(identity, &certref);
299 err = SecIdentityCopyPrivateKey(identity, &keyref);
301 if(!certref || !keyref)
304 CFDataRef certdata = SecCertificateCopyData(certref);
308 const unsigned char *p = CFDataGetBytePtr(certdata);
309 X509 *cert = d2i_X509(0, &p, CFDataGetLength(certdata));
314 CFDataRef keydata = 0;
315 SecKeyImportExportParameters params;
316 memset( ¶ms, 0,
sizeof(params) );
317 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
318 params.passphrase = CFSTR(
"pass");
319 err = SecKeychainItemExport(keyref, kSecFormatWrappedPKCS8, 0, ¶ms, &keydata);
323 BIO *bio = BIO_new_mem_buf((
void*)CFDataGetBytePtr(keydata), CFDataGetLength(keydata));
324 EVP_PKEY *key = d2i_PKCS8PrivateKey_bio(bio, 0, &password_callback, 0);
334 PKCS12 *p12 = d2i_PKCS12_bio(bio, 0);
341 int res = PKCS12_parse(p12, c->
getPKCS12Pass().c_str(), &key, &cert, NULL);
344 THROW_IOEXCEPTION(
"Failed to parse PKCS12 certificate (%s).", ERR_reason_error_string(ERR_get_error()));
348 setSignCert(cert, key);
352 *req = createRequest(cert, issuer, nonce);
355 *resp = sendRequest(*req);
358 return validateResponse(*req, *resp, cert, issuer);
369 BIO_free_all(connection);
375 connection = BIO_new_connect(const_cast<char*>(connhost.c_str()));
376 if(connection == NULL)
378 THROW_IOEXCEPTION(
"Failed to create connection with host: '%s'", connhost.c_str());
381 if(!BIO_set_conn_port(connection, const_cast<char*>(connport.c_str())))
389 if(!BIO_do_connect(connection))
409 ctx = SSL_CTX_new(SSLv23_client_method());
411 THROW_IOEXCEPTION(
"Failed to create connection with host: '%s'", connhost.c_str());
412 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
413 BIO *sconnection = BIO_new_ssl(ctx, 1);
415 THROW_IOEXCEPTION(
"Failed to create ssl connection with host: '%s'", connhost.c_str());
416 connection = BIO_push(sconnection, connection);
431 OCSP_REQUEST* req = OCSP_REQUEST_new(); OCSP_REQUEST_scope reqScope(&req);
438 OCSP_CERTID* certId = OCSP_cert_to_id(NULL, cert, issuer);
445 if(OCSP_request_add0_id(req, certId) == NULL)
451 if(OCSP_request_add1_nonce(req, const_cast<unsigned char*>(&nonce[0]), (
unsigned int)nonce.size()) == 0)
457 if(signCert && signKey && !OCSP_request_sign(req, signCert, signKey, EVP_sha1(), NULL, 0))
478 OCSP_RESPONSE* resp = 0;
484 BIO *b64 = BIO_new(BIO_f_base64());
485 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
486 BIO *hash = BIO_push(b64, BIO_new(BIO_s_mem()));
488 (void)BIO_flush(hash);
490 BIO_get_mem_data(hash, &base64);
491 auth.append(
"Basic ");
496 std::string user_agent;
497 user_agent +=
"LIB libdigidocpp/";
498 user_agent +=
VER_STR(MAJOR_VER.MINOR_VER.RELEASE_VER.BUILD_VER);
501 #if OPENSSL_VERSION_NUMBER > 0x10000000
502 OCSP_REQ_CTX *rctx = OCSP_sendreq_new(connection, const_cast<char*>(url.c_str()), 0, -1);
503 OCSP_REQ_CTX_scope rctx_scope(&rctx);
506 if(!OCSP_REQ_CTX_add1_header(rctx,
"Host", const_cast<char*>(host.c_str())))
508 if(!auth.empty() && !OCSP_REQ_CTX_add1_header(rctx,
"Proxy-Authorization", const_cast<char*>(auth.c_str())))
510 if(!OCSP_REQ_CTX_add1_header(rctx,
"User-Agent", user_agent.c_str()))
512 if(!OCSP_REQ_CTX_set1_req(rctx, req))
514 if(!OCSP_sendreq_nbio(&resp, rctx))
519 header += url +
" HTTP/1.0\r\n";
520 header +=
"Host: " + host +
"\r\n";
522 header +=
"Proxy-Authorization: " + auth +
"\r\n";
523 header +=
"User-Agent: " + user_agent +
"\r\n";
524 header +=
"X-Ignore:";
525 resp = OCSP_sendreq_bio(connection, const_cast<char*>(header.c_str()), req);
549 int respStatus = OCSP_response_status(resp);
552 case OCSP_RESPONSE_STATUS_SUCCESSFUL:
break;
553 case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
555 OCSPException e( __FILE__, __LINE__,
"OCSP request failed", respStatus );
565 OCSP_BASICRESP* basic = OCSP_response_get1_basic(resp); OCSP_BASICRESP_scope basicScope(&basic);
572 if(OCSP_check_nonce(req, basic) <= 0)
578 if(ocspCerts != NULL || certStore != NULL)
581 if(ocspCerts != NULL)
583 result = OCSP_basic_verify(basic, ocspCerts, certStore, OCSP_TRUSTOTHER);
586 if(result < 0 && certStore != NULL)
588 result = OCSP_basic_verify(basic, NULL, certStore, 0);
598 OCSP_CERTID* certId = OCSP_cert_to_id(0, cert, issuer); OCSP_CERTID_scope certIdScope(&certId);
599 int certStatus = -1;
int reason = -1;
600 ASN1_GENERALIZEDTIME *producedAt = NULL, *thisUpdate = NULL, *nextUpdate = NULL;
601 if(!OCSP_resp_find_status(basic, certId, &certStatus, &reason, &producedAt, &thisUpdate, &nextUpdate))
607 if(!OCSP_check_validity(thisUpdate, nextUpdate, skew, maxAge))
609 OCSPException e( __FILE__, __LINE__,
"OCSP response not in valid time slot.", respStatus );
617 case V_OCSP_CERTSTATUS_GOOD:
return GOOD;
618 case V_OCSP_CERTSTATUS_REVOKED:
return REVOKED;
619 case V_OCSP_CERTSTATUS_UNKNOWN:
620 default:
return UNKNOWN;
630 const unsigned char *p = &ocspResponseDER[0];
631 OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(0, &p, (
unsigned int)ocspResponseDER.size()); OCSP_RESPONSE_scope respScope(&resp);
632 OCSP_BASICRESP *basic = OCSP_response_get1_basic(resp); OCSP_BASICRESP_scope basicScope(&basic);
634 if(ocspCerts != NULL || certStore != NULL)
637 if(ocspCerts != NULL)
639 result = OCSP_basic_verify(basic, ocspCerts, certStore, OCSP_TRUSTOTHER);
642 if(result < 0 && certStore != NULL)
644 result = OCSP_basic_verify(basic, 0, certStore, OCSP_NOCHECKS);
653 unsigned long errorCode;
655 while((errorCode = ERR_get_error()) != 0)
657 ERR_error_string(errorCode, &errorMsg[0]);
658 ERR(
"OpenSSL ERROR:%ld %s",errorCode, errorMsg);
664 for(
int i = 0;
i < OCSP_resp_count(basic); ++
i)
666 OCSP_SINGLERESP *resp = OCSP_resp_get0(basic,
i);
667 switch(resp->certStatus->type)
669 case V_OCSP_CERTSTATUS_GOOD:
break;
670 case V_OCSP_CERTSTATUS_REVOKED:
672 case V_OCSP_CERTSTATUS_UNKNOWN:
687 if(ocspResponseDER.empty())
688 return std::vector<unsigned char>();
690 const unsigned char *p = &ocspResponseDER[0];
691 OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(0, &p, ocspResponseDER.size()); OCSP_RESPONSE_scope respScope(&resp);
693 return std::vector<unsigned char>();
694 OCSP_BASICRESP *basic = OCSP_response_get1_basic(resp); OCSP_BASICRESP_scope basicScope(&basic);
696 return std::vector<unsigned char>();
698 int resp_idx = OCSP_BASICRESP_get_ext_by_NID(basic, NID_id_pkix_OCSP_Nonce, -1);
699 X509_EXTENSION *resp_ext = OCSP_BASICRESP_get_ext(basic, resp_idx);
701 return std::vector<unsigned char>();
703 int size = ASN1_STRING_length(resp_ext->value);
704 unsigned char *d = ASN1_STRING_data(resp_ext->value);
705 std::vector<unsigned char> nonce(d, d + size);
713 nonce.erase(nonce.begin(), nonce.begin() + 2);
724 const unsigned char *p = &ocspResponseDER[0];
725 OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(0, &p, (
unsigned int)ocspResponseDER.size()); OCSP_RESPONSE_scope respScope(&resp);
726 OCSP_BASICRESP *basic = OCSP_response_get1_basic(resp); OCSP_BASICRESP_scope basicScope(&basic);
727 return convert(basic->tbsResponseData->producedAt);
739 char* t =
reinterpret_cast<char*
>(asn1Time->data);
741 if(asn1Time->length < 12)
752 if(t[asn1Time->length - 1] !=
'Z')
757 for(
int i = 0;
i< asn1Time->length - 1;
i++)
759 if ((t[
i] >
'9') || (t[
i] <
'0'))
766 time.tm_year = ((t[0]-
'0')*1000 + (t[1]-
'0')*100 + (t[2]-
'0')*10 + (t[3]-
'0')) - 1900;
769 time.tm_mon = ((t[4]-
'0')*10 + (t[5]-
'0')) - 1;
770 if((time.tm_mon > 11) || (time.tm_mon < 0))
776 time.tm_mday = (t[6]-
'0')*10 + (t[7]-
'0');
777 if((time.tm_mday > 31) || (time.tm_mday < 1))
783 time.tm_hour = (t[8]-
'0')*10 + (t[9]-
'0');
784 if((time.tm_hour > 23) || (time.tm_hour < 0))
790 time.tm_min = (t[10]-
'0')*10 + (t[11]-
'0');
791 if((time.tm_min > 59) || (time.tm_min < 0))
798 if(asn1Time->length >= 14 && (t[12] >=
'0') && (t[12] <=
'9') && (t[13] >=
'0') && (t[13] <=
'9'))
800 time.tm_sec = (t[12]-
'0')*10 + (t[13]-
'0');
801 if((time.tm_sec > 59) || (time.tm_sec < 0))