//Additional SSL Encryption functions QList<QByteArray> AuthorizationManager::GenerateSSLKeyPair(){ const int kBits = 4096; const int kExp = 3; char *pem_key, *pem_key_pub; RSA *rsa = RSA_generate_key(kBits, kExp, 0, 0); //Private key in PEM form: BIO *bio = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL); int keylen = BIO_pending(bio); pem_key = (char *)malloc(keylen); /* Null-terminate */ BIO_read(bio, pem_key, keylen); QByteArray privkey = QByteArray::fromRawData(pem_key, keylen); //Public key in PEM form: BIO *bio2 = BIO_new(BIO_s_mem()); PEM_write_bio_RSA_PUBKEY(bio2, rsa); int keylen2 = BIO_pending(bio2); pem_key_pub = (char *)malloc(keylen2); /* Null-terminate */ BIO_read(bio2, pem_key_pub, keylen2); QByteArray pubkey = QByteArray::fromRawData(pem_key_pub, keylen2); BIO_free_all(bio); BIO_free_all(bio2); RSA_free(rsa); //See if the keys can be loaded for use later /*RSA *rsa1= NULL; BIO *keybio1 = NULL; //qDebug() << " - Generate keybio"; keybio1 = BIO_new_mem_buf(pubkey.data(), -1); if(keybio1!=NULL){ rsa1 = PEM_read_bio_RSA_PUBKEY(keybio1, &rsa1,NULL, NULL); qDebug() << "Can read new public key:" << (rsa1!=NULL); RSA_free(rsa1); } BIO_free_all(keybio1); RSA *rsa2= NULL; BIO *keybio2 = NULL; //qDebug() << " - Generate keybio"; keybio2 = BIO_new_mem_buf(privkey.data(), -1); if(keybio2!=NULL){ rsa2 = PEM_read_bio_RSAPrivateKey(keybio2, &rsa1,NULL, NULL); qDebug() << "Can read new private key:" << (rsa2!=NULL); RSA_free(rsa2); } BIO_free_all(keybio2); */ return (QList<QByteArray>() << pubkey << privkey); }
bool Connection::readHandshake() { log_trace("Connection::readHandshake"); std::streambuf* sb = _ios->rdbuf(); if( ! sb) return true; while(_ios->rdbuf()->in_avail() > 0) { const std::streamsize bufsize = 2000; char buf[bufsize]; std::streamsize gsize = std::min( sb->in_avail(), bufsize ); std::streamsize n = sb->sgetn(buf, gsize); const int written = BIO_write(_in, buf, static_cast<int>(n)); assert(written == n); if(written <= 0 || written != n) throw SslError("BIO_write"); log_debug("read " << n << " bytes from input"); } int ret = SSL_do_handshake(_ssl); log_debug("SSL_do_handshake returns " << ret); if( ret <= 0 ) { int sslerr = SSL_get_error(_ssl, ret); if( sslerr != SSL_ERROR_WANT_READ && sslerr != SSL_ERROR_WANT_WRITE) { if(sslerr == SSL_ERROR_SSL) { char buf[255]; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); log_warn("handshake failed: " << buf); } throw HandshakeFailed("SSL handshake failed"); } } if( ret == 1 && BIO_pending(_out) <= 0 ) { _connected = true; } return BIO_pending(_out) <= 0 && SSL_want_read(_ssl); }
static void log_time(const int level, const char *txt, ASN1_TIME *t) { #ifndef HAVE_LIB_CYASSL char *cp; BIO *bio; int n; if(!t) return; bio=BIO_new(BIO_s_mem()); if(!bio) return; ASN1_TIME_print(bio, t); n=BIO_pending(bio); cp=str_alloc(n+1); n=BIO_read(bio, cp, n); if(n<0) { BIO_free(bio); str_free(cp); return; } cp[n]='\0'; BIO_free(bio); s_log(level, "%s: %s", txt, cp); str_free(cp); #else s_log(level, "%s: N/A", txt); #endif }
ustring b64_decode (const ustring &message) { bool succeeded = false; auto_BIO mem (BIO_new (BIO_s_mem ())); auto_BIO filter (BIO_new (BIO_f_base64())); ustring rv; BIO_set_flags(((BIO *) filter), BIO_FLAGS_BASE64_NO_NL); BIO_push (filter, mem); if ((BIO_write (mem, message.data (), message.size ()) >= 0) && (1 == BIO_flush (mem))) { const unsigned int Length = BIO_pending (filter); { unsigned char *tmp_buf = (unsigned char *) VHTI_alloc (Length); const int nread = BIO_read(filter, tmp_buf, Length); if (nread >= 0) { succeeded = true; rv.assign (tmp_buf, nread); } free (tmp_buf); } } if (!succeeded) throw SSL_ERROR; return rv; }
ustring b64_encode (const char *buf, const size_t length) { bool succeeded = false; ustring rv; auto_BIO mem (BIO_new (BIO_s_mem ())); auto_BIO filter (BIO_new (BIO_f_base64())); if (!mem || !filter) throw SSL_ERROR; BIO_set_flags(((BIO *) filter), BIO_FLAGS_BASE64_NO_NL); BIO_push (filter, mem); if ((BIO_write (filter, buf, length) >= 0) && (1 == BIO_flush (filter))) { const int to_read = BIO_pending (mem); unsigned char *tmp_buf = (unsigned char *) VHTI_alloc (to_read + 1); if (BIO_read(mem, tmp_buf, to_read) >= 0) { tmp_buf[to_read] = '\0'; rv.assign (tmp_buf); succeeded = true; } free (tmp_buf); } if (!succeeded) throw SSL_ERROR; return rv; }
static char *ssl_var_lookup_ssl_cert_dn_oneline(apr_pool_t *p, request_rec *r, X509_NAME *xsname) { char *result = NULL; SSLDirConfigRec *dc; int legacy_format = 0; if (r) { dc = myDirConfig(r); legacy_format = dc->nOptions & SSL_OPT_LEGACYDNFORMAT; } if (legacy_format) { char *cp = X509_NAME_oneline(xsname, NULL, 0); result = apr_pstrdup(p, cp); OPENSSL_free(cp); } else { BIO* bio; int n; unsigned long flags = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; X509_NAME_print_ex(bio, xsname, 0, flags); n = BIO_pending(bio); if (n > 0) { result = apr_palloc(p, n+1); n = BIO_read(bio, result, n); result[n] = NUL; } BIO_free(bio); } return result; }
void OpenSSLBase::pushFunc() { int wantwrite; size_t wantread; long frombio; long tobio; while( ( wantwrite = BIO_pending( m_nbio ) ) > 0 ) { if( wantwrite > m_bufsize ) wantwrite = m_bufsize; if( !wantwrite ) break; frombio = BIO_read( m_nbio, m_buf, wantwrite ); if( m_handler ) m_handler->handleEncryptedData( this, std::string( m_buf, frombio ) ); } while( ( wantread = BIO_ctrl_get_read_request( m_nbio ) ) > 0 ) { if( wantread > m_recvBuffer.length() ) wantread = m_recvBuffer.length(); if( !wantread ) break; tobio = BIO_write( m_nbio, m_recvBuffer.c_str(), static_cast<int>( wantread ) ); m_recvBuffer.erase( 0, tobio ); } }
/* * convert an X509_NAME to an RFC 2253 formatted string, optionally truncated * to maxlen characters (specify a maxlen of 0 for no length limit) */ char *modssl_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, int maxlen) { char *result = NULL; BIO *bio; int len; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253); len = BIO_pending(bio); if (len > 0) { result = apr_palloc(p, (maxlen > 0) ? maxlen+1 : len+1); if (maxlen > 0 && maxlen < len) { len = BIO_read(bio, result, maxlen); if (maxlen > 2) { /* insert trailing ellipsis if there's enough space */ apr_snprintf(result + maxlen - 3, 4, "..."); } } else { len = BIO_read(bio, result, len); } result[len] = NUL; } BIO_free(bio); return result; }
static LUA_FUNCTION(openssl_bio_gets) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int len = luaL_optint(L, 2, BIO_pending(bio)); char* buf; int ret = 1; len = len > 0 ? len : 1024; buf = malloc(len); len = BIO_gets(bio, buf, len); if (len > 0) { lua_pushlstring(L, buf, len); ret = 1; } else if (BIO_should_retry(bio)) { lua_pushstring(L, ""); ret = 1; } else { lua_pushnil(L); lua_pushinteger(L, len); ret = 2; }; free(buf); return ret; }
int hr_https_add_vars(struct http_session *hr, struct uwsgi_buffer *out) { // HTTPS (adapted from nginx) if (hr->session.ugs->mode == UWSGI_HTTP_SSL) { if (uwsgi_buffer_append_keyval(out, "HTTPS", 5, "on", 2)) return -1; hr->ssl_client_cert = SSL_get_peer_certificate(hr->ssl); if (hr->ssl_client_cert) { X509_NAME *name = X509_get_subject_name(hr->ssl_client_cert); if (name) { hr->ssl_client_dn = X509_NAME_oneline(name, NULL, 0); if (uwsgi_buffer_append_keyval(out, "HTTPS_DN", 8, hr->ssl_client_dn, strlen(hr->ssl_client_dn))) return -1; } if (uhttp.https_export_cert) { hr->ssl_bio = BIO_new(BIO_s_mem()); if (hr->ssl_bio) { if (PEM_write_bio_X509(hr->ssl_bio, hr->ssl_client_cert) > 0) { size_t cc_len = BIO_pending(hr->ssl_bio); hr->ssl_cc = uwsgi_malloc(cc_len); BIO_read(hr->ssl_bio, hr->ssl_cc, cc_len); if (uwsgi_buffer_append_keyval(out, "HTTPS_CC", 8, hr->ssl_cc, cc_len)) return -1; } } } } } else if (hr->session.ugs->mode == UWSGI_HTTP_FORCE_SSL) { hr->force_https = 1; } return 0; }
int generate_rsa_pkey() { FILE * fp; RSA * rsa_priv_key; const int kBits = 1024; const int kExp = 3; int keylen; char *pem_key; rsa_priv_key = RSA_generate_key(kBits, kExp, 0, 0); /* To get the C-string PEM form: */ BIO *bio = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(bio, rsa_priv_key, NULL, NULL, 0, NULL, NULL); keylen = BIO_pending(bio); pem_key = calloc(keylen + 1, 1); /* Null-terminate */ BIO_read(bio, pem_key, keylen); fp = fopen(f_rsa_private_key, "w"); if (fp) { fwrite(pem_key, keylen, 1, fp); fclose(fp); } else { LOG(ERROR, "[API] RSA key generation failed, could not write key to %s", f_rsa_private_key); return -1; } LOG(VERBOSE, "[API] Private key created:%s", pem_key); BIO_free_all(bio); free(pem_key); pem_key = NULL; return 0; }
void OpenSSLContext::sendPendingDataToNetwork() { int size = BIO_pending(writeBIO_); if (size > 0) { SafeByteArray data; data.resize(size); BIO_read(writeBIO_, vecptr(data), size); onDataForNetwork(data); } }
int SSLStateMachine_write_can_extract(SSLStateMachine *pMachine) { int n=BIO_pending(pMachine->pbioWrite); if(n) fprintf(stderr,"There is encrypted data available to write\n"); else fprintf(stderr,"There is no encrypted data available to write\n"); return n; }
static LUA_FUNCTION(openssl_bio_pending) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int pending = BIO_pending(bio); int wpending = BIO_wpending(bio); lua_pushinteger(L, pending); lua_pushinteger(L, wpending); return 2; }
DWORD DirCliGetX509Name( X509_NAME *pCertName, DWORD dwFlags, PSTR* ppszSubjectDN ) { DWORD dwError = 0; size_t len = 0; BIO* pBioMem = NULL; PSTR pszSubjectName = NULL; pBioMem = BIO_new(BIO_s_mem()); if (!pBioMem) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_VMAFD_ERROR(dwError); } X509_NAME_print_ex(pBioMem, pCertName, 0, dwFlags); len = BIO_pending(pBioMem); if (len <= 0) { dwError = ERROR_INVALID_DATA; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateMemory(len + 1, (PVOID*)&pszSubjectName); BAIL_ON_VMAFD_ERROR(dwError); if (BIO_read(pBioMem, pszSubjectName, len) != len) { dwError = ERROR_INVALID_STATE; BAIL_ON_VMAFD_ERROR(dwError); } *ppszSubjectDN = pszSubjectName; cleanup: if (pBioMem) { BIO_free(pBioMem); } return dwError; error: *ppszSubjectDN = NULL; goto cleanup; }
void Engine::read_socket(DataInputStream & network_in) { if( BIO_pending(bioIn) > 64*1024 ) // Enough for 4 ssl packets return; Data data; if( network_in.read(data) == 0 ) return; wLog("sock.read: %d", data.getSize()); int len = BIO_write(bioIn, data.getData(), data.getSize()); // Consumes everything by docs wLog("BIO_write: %d", len); }
int after__wrk(evt_tls_t *c, void *buf) { int pending = BIO_pending(c->app_bio_); if ( !(pending > 0) ) return 0; int p = BIO_read(c->app_bio_, buf, pending); assert(p == pending); if ( c->writer) { c->writer(c, buf, p); } return p; }
static void openssl_setenv_X509_add_PEM(liVRequest *vr, X509 *x509, const gchar *key, guint key_len) { gint n; GString *v = vr->wrk->tmp_str; BIO *bio; if (NULL != (bio = BIO_new(BIO_s_mem()))) { PEM_write_bio_X509(bio, x509); n = BIO_pending(bio); g_string_set_size(v, n); BIO_read(bio, v->str, n); BIO_free(bio); li_environment_set(&vr->env, key, key_len, GSTR_LEN(v)); } }
/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */ BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids) { STACK_OF(GENERAL_NAME) *names; BIO *bio; X509_NAME *subj; char **cpp; int i, n; if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) { *ids = NULL; return FALSE; } /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */ if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) && (bio = BIO_new(BIO_s_mem()))) { GENERAL_NAME *name; for (i = 0; i < sk_GENERAL_NAME_num(names); i++) { name = sk_GENERAL_NAME_value(names, i); if (name->type == GEN_DNS) { ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL| ASN1_STRFLGS_UTF8_CONVERT); n = BIO_pending(bio); if (n > 0) { cpp = (char **)apr_array_push(*ids); *cpp = apr_palloc(p, n+1); n = BIO_read(bio, *cpp, n); (*cpp)[n] = NUL; } } } BIO_free(bio); } if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); /* Second, the CN-IDs (commonName attributes in the subject DN) */ subj = X509_get_subject_name(x509); i = -1; while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) { cpp = (char **)apr_array_push(*ids); *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i)); } return apr_is_empty_array(*ids) ? FALSE : TRUE; }
static char *get_cert_PEM(X509 *xs) { char *result = NULL; BIO *bio; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; if (PEM_write_bio_X509(bio, xs)) { int n = BIO_pending(bio); result = malloc(n+1); n = BIO_read(bio, result, n); result[n] = '\0'; } BIO_free(bio); return result; }
static char *get_cert_valid(ASN1_UTCTIME *tm) { char *result; BIO* bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; ASN1_UTCTIME_print(bio, tm); n = BIO_pending(bio); result = malloc(n+1); n = BIO_read(bio, result, n); result[n] = '\0'; BIO_free(bio); return result; }
static char *get_cert_serial(X509 *xs) { char *result; BIO *bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs)); n = BIO_pending(bio); result = malloc(n+1); n = BIO_read(bio, result, n); result[n] = '\0'; BIO_free(bio); return result; }
bool Connection::writeHandshake() { log_trace("Connection::writeHandshake"); std::streambuf* sb = _ios->rdbuf(); if( ! sb) return false; int ret = SSL_do_handshake(_ssl); log_debug("SSL_do_handshake returns " << ret); if(ret <= 0) { const int sslerr = SSL_get_error(_ssl, ret); if(sslerr != SSL_ERROR_WANT_READ && sslerr != SSL_ERROR_WANT_WRITE) { if(sslerr == SSL_ERROR_SSL) { char buf[255]; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); log_warn("handshake failed: " << buf); } throw HandshakeFailed("SSL handshake failed"); } } if(ret == 1) { _connected = true; } if( BIO_pending(_out) ) { char buff[1000]; const int n = BIO_read(_out, buff, sizeof(buff)); log_debug("wrote " << n << " bytes to output"); if(n <= 0) throw SslError("BIO_read"); sb->sputn(buff, n); return true; } return SSL_want_write(_ssl); }
int swSSL_get_client_certificate(SSL *ssl, char *buffer, size_t length) { long len; BIO *bio; X509 *cert; cert = SSL_get_peer_certificate(ssl); if (cert == NULL) { return SW_ERR; } bio = BIO_new(BIO_s_mem()); if (bio == NULL) { swWarn("BIO_new() failed."); X509_free(cert); return SW_ERR; } if (PEM_write_bio_X509(bio, cert) == 0) { swWarn("PEM_write_bio_X509() failed."); goto failed; } len = BIO_pending(bio); if (len < 0 && len > length) { swWarn("certificate length[%ld] is too big.", len); goto failed; } int n = BIO_read(bio, buffer, len); BIO_free(bio); X509_free(cert); return n; failed: BIO_free(bio); X509_free(cert); return SW_ERR; }
static void log_time(const int level, const char *txt, ASN1_TIME *t) { char *cp; BIO *bio; int n; if(!t) return; bio=BIO_new(BIO_s_mem()); ASN1_TIME_print(bio, t); n=BIO_pending(bio); cp=str_alloc(n+1); n=BIO_read(bio, cp, n); cp[n]='\0'; BIO_free(bio); s_log(level, "%s: %s", txt, cp); str_free(cp); }
void Base64Encode::fillOutputBuffer() { int nRead = BIO_pending(m_impl->m_sink); if (nRead <= 0) return; // there is something to read from BIO auto buffer = make_unique<OBuffer>(nRead); int rLen = BIO_read(m_impl->m_sink, buffer->data(), nRead); if (rLen < 0) return; if (rLen < nRead) buffer->erase(buffer->begin() + rLen, buffer->end()); setOutputBuffer(std::move(buffer)); }
static unsigned char *get_cert_ASN1(X509 *xs, int *len) { unsigned char *result = NULL; BIO *bio; *len = 0; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; if (i2d_X509_bio(bio, xs)) { int n = BIO_pending(bio); result = malloc(n); n = BIO_read(bio, result, n); *len = n; } BIO_free(bio); return result; }
static void win_new_chain(CLI *c) { BIO *bio; int i, len; X509 *peer=NULL; STACK_OF(X509) *sk; char *chain; if(c->opt->chain) /* already cached */ return; /* this race condition is safe to ignore */ bio=BIO_new(BIO_s_mem()); if(!bio) return; sk=SSL_get_peer_cert_chain(c->ssl); for(i=0; sk && i<sk_X509_num(sk); i++) { peer=sk_X509_value(sk, i); PEM_write_bio_X509(bio, peer); } if(!sk || !c->opt->option.client) { peer=SSL_get_peer_certificate(c->ssl); if(peer) { PEM_write_bio_X509(bio, peer); X509_free(peer); } } len=BIO_pending(bio); if(len<=0) { s_log(LOG_INFO, "No peer certificate received"); BIO_free(bio); return; } chain=str_alloc(len+1); len=BIO_read(bio, chain, len); if(len<0) { s_log(LOG_ERR, "BIO_read failed"); BIO_free(bio); str_free(chain); return; } chain[len]='\0'; BIO_free(bio); str_detach(chain); /* to prevent automatic deallocation of cached value */ c->opt->chain=chain; /* this race condition is safe to ignore */ PostMessage(hwnd, WM_NEW_CHAIN, c->opt->section_number, 0); s_log(LOG_DEBUG, "Peer certificate was cached (%d bytes)", len); }
/* convert a NAME_ENTRY to UTF8 string */ char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne) { char *result = NULL; BIO* bio; int len; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; ASN1_STRING_print_ex(bio, X509_NAME_ENTRY_get_data(xsne), ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_UTF8_CONVERT); len = BIO_pending(bio); result = apr_palloc(p, len+1); len = BIO_read(bio, result, len); result[len] = NUL; BIO_free(bio); ap_xlate_proto_from_ascii(result, len); return result; }
char *dn_oneline(X509_NAME *xn) { BIO* bio; int n; char *result; unsigned long flags = XN_FLAG_RFC2253; if ((bio = BIO_new(BIO_s_mem())) == NULL) { return NULL; } X509_NAME_print_ex(bio, xn, 0, flags); n = BIO_pending(bio); result = (char *)malloc(sizeof(char *) * (n+1)); n = BIO_read(bio, result, n); result[n] = '\0'; BIO_free(bio); return result; }