int generate_ski_string() { FILE *fp; int i, j = 0, loc = 0; char* buf2 = ski = calloc(40 + 1, 1); X509 * signed_cert = 0; X509_EXTENSION *ext; fp = fopen(f_signedcert, "r"); if (fp) { signed_cert = d2i_X509_fp(fp, &signed_cert); fclose(fp); } else { //Create new one return -1; } loc = X509_get_ext_by_NID(signed_cert, NID_subject_key_identifier, -1); ext = X509_get_ext(signed_cert, loc); OPENSSL_free(signed_cert); if (ext == NULL) { return -1; } for (i = 2; i < 22; i++) { j += sprintf(buf2 + j, "%02X", ext->value->data[i]); } return j + 2; }
static int SSL_CTX_use_certificate_file_with_check( SSL_CTX *ctx, char *file, int type) { FILE *fp; X509 *x509; X509_STORE_CTX *sctx; int ret; ret = SSL_CTX_use_certificate_file(ctx, file, type); if(!ret) return ret; if(!(fp = fopen(file, "r"))) { return -1; } x509 = PEM_read_X509(fp, NULL, NULL, NULL); if(!x509){ rewind(fp); x509 = d2i_X509_fp(fp, NULL); } fclose(fp); if(!x509) return -1; X509_STORE_add_cert(ctx->cert_store, x509); sctx = X509_STORE_CTX_new(); X509_STORE_CTX_init(sctx, ctx->cert_store, x509, NULL); X509_STORE_CTX_set_verify_cb(sctx, LocalVerifyCallBack); X509_verify_cert(sctx); X509_STORE_CTX_free(sctx); CheckValidPeriod(x509); return ret; }
u32 parse_single_cert(cert_info_s *cert_buf, s8 *file_path) { u32 ret = 1; FILE *fp; X509 *x; BIO *biofile; fp = fopen(file_path, "rb"); if (NULL == fp) { return PARSE_FAIL; } x = X509_new(); if (NULL == x) { fclose(fp); return PARSE_FAIL; } if (NULL == d2i_X509_fp(fp, &x)) { biofile = BIO_new_file(file_path, "rb"); if (NULL == biofile) { X509_free(x); fclose(fp); return PARSE_FAIL; } if (!PEM_read_bio_X509(biofile, &x, 0, NULL)) { BIO_free(biofile); X509_free(x); fclose(fp); return PARSE_FAIL; } BIO_free(biofile); } ret = get_single_cert_info(x, cert_buf); X509_free(x); fclose(fp); return ret; }
SSLCertificate *ssl_certificate_find_lookup(const char *host, int port, int lookup) { char *file = NULL; char *buf = NULL; char *fqdn_host = NULL; SSLCertificate *cert = NULL; X509 *tmp_x509 = NULL; FILE *fp = NULL; if (lookup) fqdn_host = get_fqdn(host, port); else fqdn_host = g_strdup(host); buf = g_strdup_printf("%d", port); file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, "certs", G_DIR_SEPARATOR_S, fqdn_host, ".", buf, ".cert", NULL); g_free(buf); fp = fopen(file, "rb"); if (fp == NULL) { g_free(file); g_free(fqdn_host); return NULL; } if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) { cert = ssl_certificate_new_lookup(tmp_x509, fqdn_host, port, lookup); X509_free(tmp_x509); } fclose(fp); g_free(file); g_free(fqdn_host); return cert; }
void OcNetwork::sslErrorHandler(QNetworkReply* rep,const QList<QSslError> &errors) { QVariantMap account = config.getAccount(); bool ignoreSSLerrors = false; if (account["state"].toInt() == 0) { ignoreSSLerrors = account["ignoresslerror"].toBool(); } if (ignoreSSLerrors) { rep->ignoreSslErrors(); QLOG_WARN() << "Network: ignore SSL errors"; } else { foreach (const QSslError &error, errors) { QLOG_ERROR() << "Network SSL error: " << error.errorString(); } // get certificate checksum QString checksum = QString::fromLatin1(rep->sslConfiguration().peerCertificateChain().last().digest(QCryptographicHash::Md5).toHex().toLower()); // set string for temporary file path QString filePath(QDir::homePath()); filePath.append(BASE_PATH).append(QDir::separator()).append(checksum).append(".der"); // store server certificate temporary QFile x509Temp(filePath); x509Temp.open(QIODevice::WriteOnly); x509Temp.write(rep->sslConfiguration().peerCertificateChain().last().toDer()); x509Temp.close(); #if defined(MEEGO_EDITION_HARMATTAN) // set credential int credSuc = aegis_certman_set_credentials("buschtrommel-ocnews::CertOCNewsSSL"); if (credSuc != 0) qDebug() << "set credential error: " << credSuc; // open file for X509 struct FILE * crtFile; crtFile = fopen(filePath.toAscii().data(), "r"); if (crtFile == NULL) qDebug() << "Can not open cert file."; X509 * crt; crt = d2i_X509_fp(crtFile, NULL); if (crt == NULL) qDebug() << "Error importing X509 Certificate"; // get server key id aegis_key_id crtKeyId; aegis_certman_get_key_id(crt, crtKeyId); // open ssl domain domain_handle ownDomain; int openCheck = aegis_certman_open_domain("ssl-ocnews", AEGIS_CERTMAN_DOMAIN_PRIVATE, &ownDomain); if (openCheck != 0) QLOG_ERROR() << "Network: Error Opening SSL Domain: " << openCheck; int guiCheck = aegis_certman_gui_check_certificate(crt, 120); QLOG_INFO() << "Network Certificate check: " << guiCheck; if (guiCheck == 0) { // check if cert is already in domain X509 * storedCert; int loadStoredCert = aegis_certman_load_cert(ownDomain, crtKeyId, &storedCert); if (loadStoredCert == 0 && storedCert != NULL) { QLOG_INFO() << "Network Load Cert: " << loadStoredCert; // convert internal X509 structure to DER int len; unsigned char *buf; buf = NULL; len = i2d_X509(storedCert, &buf); if (len > 0) { // create Qt Certificate from buffer QByteArray buffer(reinterpret_cast<const char*>(buf), len); QSslCertificate sslCert(buffer, QSsl::Der); // create list and append cert QList<QSslCertificate> sslCerts; sslCerts.append(sslCert); // put ssl into ssl error for ignored errors QSslError sslError(QSslError::SelfSignedCertificate, sslCerts.at(0)); QList<QSslError> expectedSslErrors; expectedSslErrors.append(sslError); // add certificate to socket and current configuration QSslSocket::addDefaultCaCertificates(sslCerts); QList<QSslCipher> ciphers = rep->sslConfiguration().ciphers(); QSslConfiguration sslConfig; sslConfig.setCiphers(ciphers); sslConfig.setCaCertificates(sslCerts); rep->setSslConfiguration(sslConfig); // ignore only this ssl error rep->ignoreSslErrors(expectedSslErrors); } else { QLOG_ERROR() << "Network: Can not decode cert to DER."; } } else { int addCheck = aegis_certman_add_cert(ownDomain, crt); QLOG_INFO() << "Network Add Cert: " << addCheck; // convert internal X509 structure to DER int len; unsigned char *buf; buf = NULL; len = i2d_X509(crt, &buf); if (len > 0) { // create Qt Certificate from buffer QByteArray buffer(reinterpret_cast<const char*>(buf), len); QSslCertificate sslCert(buffer, QSsl::Der); // create list and append cert QList<QSslCertificate> sslCerts; sslCerts.append(sslCert); // put ssl into ssl error for ignored errors QSslError sslError(QSslError::SelfSignedCertificate, sslCerts.at(0)); QList<QSslError> expectedSslErrors; expectedSslErrors.append(sslError); // add certificate to socket and current configuration QSslSocket::addDefaultCaCertificates(sslCerts); QList<QSslCipher> ciphers = rep->sslConfiguration().ciphers(); QSslConfiguration sslConfig; sslConfig.setCiphers(ciphers); sslConfig.setCaCertificates(sslCerts); rep->setSslConfiguration(sslConfig); // ignore only these ssl error rep->ignoreSslErrors(expectedSslErrors); } else { QLOG_ERROR() << "Network: Can not decode cert to DER."; } } } else { // remove cert if not approved int removeCheck = aegis_certman_rm_cert(ownDomain, crtKeyId); QLOG_INFO() << "Network Remove Cert: " << removeCheck; } aegis_certman_close_domain(ownDomain); x509Temp.remove(); // remove temporary cert file #else // rep->ignoreSslErrors(); rep->abort(); QLOG_WARN() << "Abort network operation..."; #endif } }
/* ToDo: Create Access to OpenSSL certificate store => Only API to In-Memory-Store is available for version 0.9.8x => Wait until Directory- and/or File-Store is available */ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_LoadCertificate( OpcUa_PKIProvider* a_pProvider, OpcUa_Void* a_pLoadHandle, OpcUa_Void* a_pCertificateStore, OpcUa_ByteString* a_pCertificate) { OpcUa_Byte* buf = OpcUa_Null; OpcUa_Byte* p = OpcUa_Null; FILE* pCertificateFile = OpcUa_Null; X509* pTmpCert = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_LoadCertificate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_pLoadHandle); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); /* read DER certificates */ pCertificateFile = fopen((const char*)a_pLoadHandle, "r"); /* check for valid file handle */ OpcUa_GotoErrorIfTrue((pCertificateFile == OpcUa_Null), OpcUa_BadInvalidArgument); if(!(pTmpCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } a_pCertificate->Length = i2d_X509(pTmpCert, NULL); buf = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertificate->Length); OpcUa_GotoErrorIfAllocFailed(buf); p = buf; for (;;) { i2d_X509(pTmpCert, &p); X509_free(pTmpCert); if(!(pTmpCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null))) { break; } p = OpcUa_P_Memory_ReAlloc(buf, a_pCertificate->Length + i2d_X509(pTmpCert, NULL)); OpcUa_GotoErrorIfAllocFailed(p); buf = p; p = buf + a_pCertificate->Length; a_pCertificate->Length += i2d_X509(pTmpCert, NULL); } if(fclose(pCertificateFile) != 0) { pCertificateFile = OpcUa_Null; uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } a_pCertificate->Data = buf; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pCertificateFile != OpcUa_Null) { fclose(pCertificateFile); } if(pTmpCert != OpcUa_Null) { X509_free(pTmpCert); } if(buf != OpcUa_Null) { OpcUa_P_Memory_Free(buf); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_PKI_ValidateCertificate *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_ValidateCertificate( OpcUa_PKIProvider* a_pProvider, OpcUa_ByteString* a_pCertificate, OpcUa_Void* a_pCertificateStore, OpcUa_Int* a_pValidationCode /* Validation return codes from OpenSSL */ ) { OpcUa_P_OpenSSL_CertificateStore_Config* pCertificateStoreCfg; const unsigned char* p; X509* pX509Certificate = OpcUa_Null; STACK_OF(X509)* pX509Chain = OpcUa_Null; X509_STORE_CTX* verify_ctx = OpcUa_Null; /* holds data used during verification process */ char CertFile[MAX_PATH]; struct dirent **dirlist = NULL; int numCertificates = 0, i; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_ValidateCertificate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore); OpcUa_ReturnErrorIfArgumentNull(a_pValidationCode); pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle; /* convert DER encoded bytestring certificate to openssl X509 certificate */ p = a_pCertificate->Data; if(!(pX509Certificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Length))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } while(p < a_pCertificate->Data + a_pCertificate->Length) { X509* pX509AddCertificate; if(!(pX509AddCertificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Data + a_pCertificate->Length - p))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pX509Chain == NULL) { pX509Chain = sk_X509_new_null(); OpcUa_GotoErrorIfAllocFailed(pX509Chain); } if(!sk_X509_push(pX509Chain, pX509AddCertificate)) { X509_free(pX509AddCertificate); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } /* create verification context and initialize it */ if(!(verify_ctx = X509_STORE_CTX_new())) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } #if (OPENSSL_VERSION_NUMBER > 0x00907000L) if(X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } #else X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain); #endif if(X509_STORE_CTX_set_app_data(verify_ctx, pCertificateStoreCfg) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL_EXCEPT_SELF_SIGNED && !verify_ctx->check_issued(verify_ctx, pX509Certificate, pX509Certificate)) { /* set the flags of the store so that CRLs are consulted */ X509_STORE_CTX_set_flags(verify_ctx, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } /* verify the certificate */ *a_pValidationCode = X509_V_OK; if(X509_verify_cert(verify_ctx) <= 0) { *a_pValidationCode = verify_ctx->error; switch(verify_ctx->error) { case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: { uStatus = OpcUa_BadCertificateTimeInvalid; break; } case X509_V_ERR_CERT_REVOKED: { uStatus = OpcUa_BadCertificateRevoked; break; } case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: { uStatus = OpcUa_BadCertificateUntrusted; break; } case X509_V_ERR_CERT_SIGNATURE_FAILURE: { uStatus = OpcUa_BadSecurityChecksFailed; break; } default: { uStatus = OpcUa_BadCertificateInvalid; } } OpcUa_GotoErrorIfBad(uStatus); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REQUIRE_CHAIN_CERTIFICATE_IN_TRUST_LIST) { FILE* pCertificateFile; X509* pTrustCert; STACK_OF(X509)* chain; int trusted, n; chain = X509_STORE_CTX_get_chain(verify_ctx); trusted = 0; if(pCertificateStoreCfg->CertificateTrustListLocation == NULL || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0') { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* read DER certificates */ pCertificateFile = fopen(CertFile, "r"); if(pCertificateFile == OpcUa_Null) { continue; /* ignore access errors */ } pTrustCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null); fclose(pCertificateFile); if(pTrustCert == OpcUa_Null) { continue; /* ignore parse errors */ } for(n = 0; n < sk_X509_num(chain); n++) { if (X509_cmp(sk_X509_value(chain, n), pTrustCert) == 0) break; } X509_free(pTrustCert); if(n < sk_X509_num(chain)) { trusted = 1; break; } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; if(!trusted) { uStatus = OpcUa_BadCertificateUntrusted; OpcUa_GotoErrorIfBad(uStatus); } } X509_STORE_CTX_free(verify_ctx); X509_free(pX509Certificate); if(pX509Chain != OpcUa_Null) { sk_X509_pop_free(pX509Chain, X509_free); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(dirlist != NULL) { for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); } if(verify_ctx != OpcUa_Null) { X509_STORE_CTX_free(verify_ctx); } if(pX509Certificate != OpcUa_Null) { X509_free(pX509Certificate); } if(pX509Chain != OpcUa_Null) { sk_X509_pop_free(pX509Chain, X509_free); } OpcUa_FinishErrorHandling; }
void RunEaSession(SSL* ssl, void* data) { int rfd, wfd; FILE* rfp; FILE* wfp; SetupFileDescriptors(ssl, &rfd, &rfp, &wfd, &wfp); RsaDevice device = (RsaDevice)data; // Device makes entropy request BIGNUM* v1 = BN_new(); BIGNUM* v2 = BN_new(); BIGNUM* v3 = BN_new(); BIGNUM* v4 = BN_new(); CHECK_CALL(v1); CHECK_CALL(v2); CHECK_CALL(RsaDevice_GenEntropyRequest(device, v1, v2)); PrintTime("Sending commits to EA"); // Send mode flag CHECK_CALL(fprintf(wfp, "%d\n", RSA_CLIENT)); CHECK_CALL(!fflush(wfp)); CHECK_CALL(WriteOneBignum(STRING_COMMIT_X, sizeof(STRING_COMMIT_X), wfp, v1)); CHECK_CALL(WriteOneBignum(STRING_COMMIT_Y, sizeof(STRING_COMMIT_Y), wfp, v2)); CHECK_CALL(!fflush(wfp)); PrintTime("...done"); // Read x', y' from EA PrintTime("Reading entropy from EA"); CHECK_CALL(ReadOneBignum(&v1, rfp, STRING_X_PRIME)); CHECK_CALL(ReadOneBignum(&v2, rfp, STRING_Y_PRIME)); PrintTime("...done"); CHECK_CALL(RsaDevice_SetEntropyResponse(device, v1, v2)); // Send proof to EA ProductEvidence ev; CHECK_CALL(ev); X509_REQ* req = X509_REQ_new(); CHECK_CALL(req); CHECK_CALL(RsaDevice_GenEaSigningRequest(device, req, v1, v2, v3, &ev)); PrintTime("Sending cert to EA"); CHECK_CALL(i2d_X509_REQ_fp(wfp, req)); //fprintf(wfp, "\n"); CHECK_CALL(!fflush(wfp)); CHECK_CALL(WriteOneBignum(STRING_DELTA_X, sizeof(STRING_DELTA_X), wfp, v1)); CHECK_CALL(WriteOneBignum(STRING_DELTA_Y, sizeof(STRING_DELTA_Y), wfp, v2)); CHECK_CALL(WriteOneBignum(STRING_MODULUS_RAND, sizeof(STRING_MODULUS_RAND), wfp, v3)); CHECK_CALL(ProductEvidence_Serialize(ev, wfp)); CHECK_CALL(!fflush(wfp)); PrintTime("...done"); X509_REQ_free(req); ProductEvidence_Free(ev); X509* cert = NULL; PrintTime("Reading cert from EA"); if(!(cert = d2i_X509_fp(rfp, NULL))) { fatal("Could not read X509 response"); } PrintTime("...done"); fclose(rfp); fclose(wfp); BN_clear_free(v1); BN_clear_free(v2); BN_clear_free(v3); BN_clear_free(v4); // Give EA signature back to device CHECK_CALL(RsaDevice_SetEaCertResponse(device, cert)); X509_free(cert); return; }