static PKCS11H_BOOL __pkcs11h_openssl_session_setRSA( IN const pkcs11h_openssl_session_t openssl_session, IN EVP_PKEY * evp ) { PKCS11H_BOOL ret = FALSE; RSA *rsa = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setRSA - entered openssl_session=%p, evp=%p", (void *)openssl_session, (void *)evp ); if ( (rsa = EVP_PKEY_get1_RSA (evp)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key"); goto cleanup; } RSA_set_method (rsa, __openssl_methods.rsa); RSA_set_ex_data (rsa, __openssl_methods.rsa_index, openssl_session); #if OPENSSL_VERSION_NUMBER < 0x10100001L rsa->flags |= RSA_FLAG_SIGN_VER; #endif #ifdef BROKEN_OPENSSL_ENGINE if (!rsa->engine) { rsa->engine = ENGINE_get_default_RSA (); } ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->rsa); _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled"); #endif ret = TRUE; cleanup: if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setRSA - return ret=%d", ret ); return ret; }
RSA * RSA_new_method(ENGINE *engine) { RSA *rsa; rsa = calloc(1, sizeof(*rsa)); if (rsa == NULL) return NULL; rsa->references = 1; if (engine) { ENGINE_up_ref(engine); rsa->engine = engine; } else { rsa->engine = ENGINE_get_default_RSA(); } if (rsa->engine) { rsa->meth = ENGINE_get_RSA(rsa->engine); if (rsa->meth == NULL) { ENGINE_finish(engine); free(rsa); return 0; } } if (rsa->meth == NULL) rsa->meth = rk_UNCONST(RSA_get_default_method()); (*rsa->meth->init)(rsa); return rsa; }
void ca_engine_init(void) { ENGINE *e; const char *errstr, *name; if ((e = ENGINE_get_default_RSA()) == NULL) { if ((e = ENGINE_new()) == NULL) { errstr = "ENGINE_new"; goto fail; } if (!ENGINE_set_name(e, rsae_method.name)) { errstr = "ENGINE_set_name"; goto fail; } if ((rsa_default = RSA_get_default_method()) == NULL) { errstr = "RSA_get_default_method"; goto fail; } } else if ((rsa_default = ENGINE_get_RSA(e)) == NULL) { errstr = "ENGINE_get_RSA"; goto fail; } if ((name = ENGINE_get_name(e)) == NULL) name = "unknown RSA engine"; log_debug("debug: %s: using %s", __func__, name); if (rsa_default->flags & RSA_FLAG_SIGN_VER) fatalx("unsupported RSA engine"); if (rsa_default->rsa_mod_exp == NULL) rsae_method.rsa_mod_exp = NULL; if (rsa_default->bn_mod_exp == NULL) rsae_method.bn_mod_exp = NULL; if (rsa_default->rsa_keygen == NULL) rsae_method.rsa_keygen = NULL; rsae_method.flags = rsa_default->flags | RSA_METHOD_FLAG_NO_CHECK; rsae_method.app_data = rsa_default->app_data; if (!ENGINE_set_RSA(e, &rsae_method)) { errstr = "ENGINE_set_RSA"; goto fail; } if (!ENGINE_set_default_RSA(e)) { errstr = "ENGINE_set_default_RSA"; goto fail; } return; fail: ssl_error(errstr); fatalx("%s", errstr); }
RSA *RSA_new_method(ENGINE *engine) { RSA *ret; ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); return NULL; } ret->meth = RSA_get_default_method(); #ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); OPENSSL_free(ret); return NULL; } ret->engine = engine; } else ret->engine = ENGINE_get_default_RSA(); if (ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if (!ret->meth) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); ENGINE_finish(ret->engine); OPENSSL_free(ret); return NULL; } } #endif ret->references = 1; ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif OPENSSL_free(ret); return (NULL); } if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); OPENSSL_free(ret); ret = NULL; } return (ret); }
RSA *RSA_new_method(ENGINE *engine) { RSA *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } ret->meth = RSA_get_default_method(); #ifndef OPENSSL_NO_ENGINE ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (engine) { if (!ENGINE_init(engine)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; } else { ret->engine = ENGINE_get_default_RSA(); } if (ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if (ret->meth == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); goto err; } } #endif ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { goto err; } if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); goto err; } return ret; err: RSA_free(ret); return NULL; }
static void suspend_engine(void *ctx,int *mem) { ENGINE *e=(ENGINE *)ctx; *mem=0; if(ENGINE_get_default_RSA()) { *mem|=0x01; ENGINE_unregister_RSA(e); } if(ENGINE_get_default_DSA()) { *mem|=0x02; ENGINE_unregister_DSA(e); } #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if(ENGINE_get_default_EC()) { *mem|=0x04; ENGINE_unregister_EC(e); } #else if(ENGINE_get_default_ECDH()) { *mem|=0x04; ENGINE_unregister_ECDH(e); } if(ENGINE_get_default_ECDSA()) { *mem|=0x08; ENGINE_unregister_ECDSA(e); } #endif if(ENGINE_get_default_DH()) { *mem|=0x10; ENGINE_unregister_DH(e); } if(ENGINE_get_default_RAND()) { *mem|=0x20; ENGINE_unregister_RAND(e); } }
Engine* Engines::getEngineDefault(Engine::Algorithm algorithm) throw (EngineException) { ENGINE *eng = NULL; switch (algorithm) { case Engine::RSA: eng = ENGINE_get_default_RSA(); break; case Engine::DSA: eng = ENGINE_get_default_DSA(); break; // case Engines::DH: // e = ENGINE_get_default_DH(); // break; case Engine::RAND: eng = ENGINE_get_default_RAND(); break; // case Engine::ECDH: // e = ENGINE_get_default_ECDH(); // break; case Engine::ECDSA: eng = ENGINE_get_default_ECDSA(); break; // case Engine::CIPHERS: // e = ENGINE_get_default_CIPHERS(); // break; // case Engine::DIGESTS: // e = ENGINE_get_default_DIGESTS(); // break; // case Engine::STORE: case Engine::ALL: case Engine::NONE: default: break; } if (!eng) { throw EngineException(EngineException::ENGINE_NOT_FOUND, "Engines::getEngineDefault"); } return new Engine(eng); }
RSA *RSA_new_method(ENGINE *engine) { RSA *ret; ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); if (ret == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); return NULL; } ret->meth = RSA_get_default_method(); #ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); OPENSSL_free(ret); return NULL; } ret->engine = engine; } else ret->engine = ENGINE_get_default_RSA(); if(ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if(!ret->meth) { RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); ENGINE_finish(ret->engine); OPENSSL_free(ret); return NULL; } } #endif ret->pad=0; ret->version=0; ret->n=NULL; ret->e=NULL; ret->d=NULL; ret->p=NULL; ret->q=NULL; ret->dmp1=NULL; ret->dmq1=NULL; ret->iqmp=NULL; ret->references=1; ret->_method_mod_n=NULL; ret->_method_mod_p=NULL; ret->_method_mod_q=NULL; ret->blinding=NULL; ret->mt_blinding=NULL; ret->bignum_data=NULL; ret->flags=ret->meth->flags; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); #endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; } return(ret); }
U8_EXPORT ssize_t u8_cryptic (int do_encrypt,const char *cname, const unsigned char *key,int keylen, const unsigned char *iv,int ivlen, u8_block_reader reader,u8_block_writer writer, void *readstate,void *writestate, u8_context caller) { if (strncasecmp(cname,"rsa",3)==0) { ENGINE *eng=ENGINE_get_default_RSA(); EVP_PKEY _pkey, *pkey; EVP_PKEY_CTX *ctx; int pubkeyin=(strncasecmp(cname,"rsapub",6)==0); const unsigned char *scankey=key; struct U8_BYTEBUF bb; int retval=-1; if (pubkeyin) pkey=d2i_PUBKEY(NULL,&scankey,keylen); else pkey=d2i_PrivateKey((EVP_PKEY_RSA),NULL,&scankey,keylen); if (!(pkey)) ctx=NULL; else { #if (OPENSSL_VERSION_NUMBER>=0x1000204fL) ctx=EVP_PKEY_CTX_new(pkey,eng); #else ctx=EVP_PKEY_CTX_new(pkey,NULL); #endif } if (ctx) { memset(&bb,0,sizeof(bb)); bb.u8_direction=u8_output_buffer; bb.u8_buf=bb.u8_ptr=(u8_byte *)u8_malloc(1024); bb.u8_lim=(u8_byte *)(bb.u8_buf+1024); bb.u8_growbuf=1; fill_bytebuf(&bb,reader,readstate);} if (!(ctx)) {} else if ((pubkeyin)? ((do_encrypt)?((retval=EVP_PKEY_encrypt_init(ctx))<0): ((retval=EVP_PKEY_verify_recover_init(ctx))<0)): ((do_encrypt)?((retval=EVP_PKEY_sign_init(ctx))<0): ((retval=EVP_PKEY_decrypt_init(ctx))<0))) {} else { unsigned char *in=bb.u8_buf; size_t inlen=bb.u8_ptr-bb.u8_buf; unsigned char *out=NULL; size_t outlen; if (pubkeyin) { if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,NULL,&outlen,in,inlen); else retval=EVP_PKEY_verify_recover(ctx,NULL,&outlen,in,inlen);} else if (do_encrypt) retval=EVP_PKEY_sign(ctx,NULL,&outlen,in,inlen); else retval=EVP_PKEY_decrypt(ctx,NULL,&outlen,in,inlen); if (retval<0) {} else if ((out=u8_malloc(outlen))==NULL) {} else if (pubkeyin) { if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,out,&outlen,in,inlen); else retval=EVP_PKEY_verify_recover(ctx,out,&outlen,in,inlen);} else if (do_encrypt) retval=EVP_PKEY_sign(ctx,out,&outlen,in,inlen); else retval=EVP_PKEY_decrypt(ctx,out,&outlen,in,inlen); if (retval<0) {} else retval=writer(out,outlen,writestate); if (out) u8_free(out);} u8_free(bb.u8_buf); if (retval<0) { unsigned long err=ERR_get_error(); char buf[512]; buf[0]='\0'; ERR_error_string_n(err,buf,512); u8_seterr(u8_InternalCryptoError,OPENSSL_CRYPTIC,u8_fromlibc((char *)buf)); ERR_clear_error();} if (ctx) EVP_PKEY_CTX_free(ctx); if (pkey) EVP_PKEY_free(pkey); return retval;} else { EVP_CIPHER_CTX ctx; int inlen, outlen, retval=0; ssize_t totalout=0, totalin=0; unsigned char inbuf[1024], outbuf[1024+EVP_MAX_BLOCK_LENGTH]; const EVP_CIPHER *cipher=((cname)?(EVP_get_cipherbyname(cname)): (EVP_aes_128_cbc())); if (cipher) { int needkeylen=EVP_CIPHER_key_length(cipher); int needivlen=EVP_CIPHER_iv_length(cipher); int blocksize=EVP_CIPHER_block_size(cipher); if (blocksize>1024) blocksize=1024; u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC, " %s cipher=%s, keylen=%d/%d, ivlen=%d/%d, blocksize=%d\n", ((do_encrypt)?("encrypt"):("decrypt")), cname,keylen,needkeylen,ivlen,needivlen,blocksize); if ((needivlen)&&(ivlen)&&(ivlen!=needivlen)) return u8_reterr(u8_BadCryptoIV, ((caller)?(caller):(OPENSSL_CRYPTIC)), u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname)); memset(&ctx,0,sizeof(ctx)); EVP_CIPHER_CTX_init(&ctx); retval=EVP_CipherInit(&ctx, cipher, NULL, NULL, do_encrypt); if (retval==0) return u8_reterr(u8_CipherInit_Failed, ((caller)?(caller):(OPENSSL_CRYPTIC)), u8_strdup(cname)); retval=EVP_CIPHER_CTX_set_key_length(&ctx,keylen); if (retval==0) return u8_reterr(u8_BadCryptoKey, ((caller)?(caller):(OPENSSL_CRYPTIC)), u8_mkstring("%d!=%d(%s)",keylen,needkeylen,cname)); if ((needivlen)&&(ivlen!=needivlen)) return u8_reterr(u8_BadCryptoIV, ((caller)?(caller):(OPENSSL_CRYPTIC)), u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname)); retval=EVP_CipherInit(&ctx, cipher, key, iv, do_encrypt); if (retval==0) return u8_reterr(u8_CipherInit_Failed, ((caller)?(caller):(OPENSSL_CRYPTIC)), u8_strdup(cname)); while (1) { inlen = reader(inbuf,blocksize,readstate); if (inlen <= 0) { u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC, "Finished %s(%s) with %ld in, %ld out", ((do_encrypt)?("encrypt"):("decrypt")), cname,totalin,totalout); break;} else totalin=totalin+inlen; if (!(EVP_CipherUpdate(&ctx,outbuf,&outlen,inbuf,inlen))) { char *details=u8_malloc(256); unsigned long err=ERR_get_error(); ERR_error_string_n(err,details,256); EVP_CIPHER_CTX_cleanup(&ctx); return u8_reterr(u8_InternalCryptoError, ((caller)?(caller):((u8_context)"u8_cryptic")), details);} else { u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC, "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes" " in=<%v>\n out=<%v>", ((do_encrypt)?("encrypt"):("decrypt")),cname, inlen,totalin,outlen,totalout+outlen, inbuf,inlen,outbuf,outlen); writer(outbuf,outlen,writestate); totalout=totalout+outlen;}} if (!(EVP_CipherFinal(&ctx,outbuf,&outlen))) { char *details=u8_malloc(256); unsigned long err=ERR_get_error(); ERR_error_string_n(err,details,256); EVP_CIPHER_CTX_cleanup(&ctx); return u8_reterr(u8_InternalCryptoError, ((caller)?(caller):(OPENSSL_CRYPTIC)), details);} else { writer(outbuf,outlen,writestate); u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC, "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes" "\n final out=<%v>", ((do_encrypt)?("encrypt"):("decrypt")),cname, inlen,totalin,outlen,totalout+outlen, outbuf,outlen); EVP_CIPHER_CTX_cleanup(&ctx); totalout=totalout+outlen; return totalout;}} else { char *details=u8_malloc(256); unsigned long err=ERR_get_error(); ERR_error_string_n(err,details,256); return u8_reterr("Unknown cipher", ((caller)?(caller):((u8_context)"u8_cryptic")), details);} } }
static VALUE ORPV__verify_pss_sha1(VALUE self, VALUE vPubKey, VALUE vSig, VALUE vHashData, VALUE vSaltLen) { enum ORPV_errors err = OK; BIO * pkey_bio = NULL; RSA * rsa_pub_key = NULL; EVP_PKEY * pkey = NULL; EVP_PKEY_CTX * pkey_ctx = NULL; char * pub_key = NULL; int verify_rval = -1, salt_len; char ossl_err_strs[(OSSL_ERR_STR_LEN + 2) * ORPV_MAX_ERRS] = ""; if (ERR_peek_error()) { err = EXTERNAL; goto Cleanup; } vPubKey = StringValue(vPubKey); vSig = StringValue(vSig); vHashData = StringValue(vHashData); salt_len = NUM2INT(vSaltLen); if (RSTRING_LEN(vPubKey) > (long)INT_MAX) { err = KEY_OVERFLOW; goto Cleanup; } pub_key = malloc(RSTRING_LEN(vPubKey)); if (! pub_key) { err = NOMEM; goto Cleanup; } memcpy(pub_key, StringValuePtr(vPubKey), RSTRING_LEN(vPubKey)); pkey_bio = BIO_new_mem_buf(pub_key, (int)RSTRING_LEN(vPubKey)); rsa_pub_key = PEM_read_bio_RSA_PUBKEY(pkey_bio, NULL, NULL, NULL); if (! rsa_pub_key) { err = PUBKEY_PARSE; goto Cleanup; } pkey = EVP_PKEY_new(); if (! pkey) { err = PKEY_INIT; goto Cleanup; } if (! EVP_PKEY_set1_RSA(pkey, rsa_pub_key)) { err = RSA_ASSIGN; goto Cleanup; } pkey_ctx = EVP_PKEY_CTX_new(pkey, ENGINE_get_default_RSA()); if (! pkey_ctx) { err = PKEY_CTX_INIT; goto Cleanup; } if (EVP_PKEY_verify_init(pkey_ctx) <= 0) { err = VERIFY_INIT; goto Cleanup; } if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, EVP_sha1()) <= 0) { err = SET_SIG_MD; goto Cleanup; } if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0) { err = SET_PADDING; goto Cleanup; } if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) <= 0) { err = SET_SALTLEN; goto Cleanup; } verify_rval = EVP_PKEY_verify(pkey_ctx, (unsigned char*)StringValuePtr(vSig), (size_t)RSTRING_LEN(vSig), (unsigned char*)StringValuePtr(vHashData), (size_t)RSTRING_LEN(vHashData)); Cleanup: /* * BIO * pkey_bio = NULL; * RSA * rsa_pub_key = NULL; * EVP_PKEY * pkey = NULL; * EVP_PKEY_CTX * pkey_ctx = NULL; * char * pub_key = NULL; */ if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx); if (pkey) EVP_PKEY_free(pkey); if (rsa_pub_key) RSA_free(rsa_pub_key); if (pkey_bio) BIO_free(pkey_bio); if (pub_key) free(pub_key); switch (err) { case OK: switch (verify_rval) { case 1: return Qtrue; case 0: return Qfalse; default: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "An error occurred during validation.\n%s", ossl_err_strs); } break; case EXTERNAL: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_eRuntimeError, "OpenSSL was in an error state prior to invoking this verification.\n%s", ossl_err_strs); break; case KEY_OVERFLOW: rb_raise(rb_cRSAError, "Your public key is too big. How is that even possible?"); break; case NOMEM: rb_raise(rb_const_get_at(rb_mErrno, rb_intern("ENOMEM")), "Insufficient memory to allocate pubkey copy. Woof."); break; case PUBKEY_PARSE: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Error parsing public key\n%s", ossl_err_strs); break; case PKEY_INIT: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to initialize PKEY\n%s", ossl_err_strs); break; case RSA_ASSIGN: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to assign RSA object to PKEY\n%s", ossl_err_strs); break; case PKEY_CTX_INIT: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to initialize PKEY context.\n%s", ossl_err_strs); break; case VERIFY_INIT: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to initialize verification process.\n%s", ossl_err_strs); break; case SET_SIG_MD: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to set signature message digest to SHA1.\n%s", ossl_err_strs); break; case SET_PADDING: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to set PSS padding.\n%s", ossl_err_strs); break; case SET_SALTLEN: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_cRSAError, "Failed to set salt length.\n%s", ossl_err_strs); break; default: bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS); rb_raise(rb_eRuntimeError, "Something has gone horribly wrong.\n%s", ossl_err_strs); } return Qnil; }