janus_dtls_srtp *janus_dtls_srtp_create(void *ice_component, janus_dtls_role role) { janus_ice_component *component = (janus_ice_component *)ice_component; if(component == NULL) { JANUS_LOG(LOG_ERR, "No component, no DTLS...\n"); return NULL; } janus_ice_stream *stream = component->stream; if(!stream) { JANUS_LOG(LOG_ERR, "No stream, no DTLS...\n"); return NULL; } janus_ice_handle *handle = stream->handle; if(!handle || !handle->agent) { JANUS_LOG(LOG_ERR, "No handle/agent, no DTLS...\n"); return NULL; } janus_dtls_srtp *dtls = calloc(1, sizeof(janus_dtls_srtp)); if(dtls == NULL) { JANUS_LOG(LOG_FATAL, "Memory error!\n"); return NULL; } /* Create SSL context, at last */ dtls->srtp_valid = 0; dtls->dtls_last_msg = NULL; dtls->dtls_last_len = 0; dtls->ssl = SSL_new(janus_dtls_get_ssl_ctx()); if(!dtls->ssl) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] No component DTLS SSL session??\n", handle->handle_id); janus_dtls_srtp_destroy(dtls); return NULL; } SSL_set_ex_data(dtls->ssl, 0, dtls); SSL_set_info_callback(dtls->ssl, janus_dtls_callback); dtls->read_bio = BIO_new(BIO_s_mem()); if(!dtls->read_bio) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error creating read BIO!\n", handle->handle_id); janus_dtls_srtp_destroy(dtls); return NULL; } BIO_set_mem_eof_return(dtls->read_bio, -1); dtls->write_bio = BIO_new(BIO_s_mem()); if(!dtls->write_bio) { JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error creating write BIO!\n", handle->handle_id); janus_dtls_srtp_destroy(dtls); return NULL; } BIO_set_mem_eof_return(dtls->write_bio, -1); SSL_set_bio(dtls->ssl, dtls->read_bio, dtls->write_bio); dtls->dtls_role = role; if(dtls->dtls_role == JANUS_DTLS_ROLE_CLIENT) { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Setting connect state (DTLS client)\n", handle->handle_id); SSL_set_connect_state(dtls->ssl); } else { JANUS_LOG(LOG_VERB, "[%"SCNu64"] Setting accept state (DTLS server)\n", handle->handle_id); SSL_set_accept_state(dtls->ssl); } /* Done */ dtls->component = component; return dtls; }
tnet_dtls_socket_handle_t* tnet_dtls_socket_create(struct tnet_socket_s* wrapped_sock, struct ssl_ctx_st* ssl_ctx) { #if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled"); return tsk_null; #else tnet_dtls_socket_t* socket; if (!wrapped_sock || !ssl_ctx){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } if ((socket = tsk_object_new(tnet_dtls_socket_def_t))) { const tsk_bool_t set_mtu = TNET_SOCKET_TYPE_IS_DGRAM(wrapped_sock->type) || 1; //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP socket->wrapped_sock = tsk_object_ref(wrapped_sock); if (!(socket->ssl = SSL_new(ssl_ctx))) { TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null)); TSK_OBJECT_SAFE_FREE(socket); return tsk_null; } if (set_mtu) { SSL_set_options(socket->ssl, SSL_OP_NO_QUERY_MTU); SSL_set_mtu(socket->ssl, TNET_DTLS_MTU - 28); socket->ssl->d1->mtu = TNET_DTLS_MTU - 28; } if (!(socket->rbio = BIO_new(BIO_s_mem())) || !(socket->wbio = BIO_new(BIO_s_mem()))){ TSK_DEBUG_ERROR("BIO_new_socket(%d) failed [%s]", socket->wrapped_sock->fd, ERR_error_string(ERR_get_error(), tsk_null)); if (socket->rbio){ BIO_free(socket->rbio); } if (socket->wbio){ BIO_free(socket->wbio); } TSK_OBJECT_SAFE_FREE(socket); return tsk_null; } BIO_set_mem_eof_return(socket->rbio, -1); BIO_set_mem_eof_return(socket->wbio, -1); SSL_set_bio(socket->ssl, socket->rbio, socket->wbio); SSL_set_mode(socket->ssl, SSL_MODE_AUTO_RETRY); SSL_set_read_ahead(socket->ssl, 1); if (set_mtu) { BIO_ctrl(SSL_get_wbio(socket->ssl), BIO_CTRL_DGRAM_SET_MTU, TNET_DTLS_MTU - 28, NULL); } if ((socket->verify_peer = (SSL_CTX_get_verify_mode(ssl_ctx) != SSL_VERIFY_NONE))){ TSK_DEBUG_INFO("SSL cert verify: ON"); socket->verify_peer = tsk_true; SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert); } else { TSK_DEBUG_ERROR("Verity not enabled"); } SSL_set_app_data(socket->ssl, socket); } return socket; #endif }
/* * NOTE: Transfers control of the BIOs - this function will free them on error */ int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl, SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio) { SSL *serverssl = NULL, *clientssl = NULL; BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL; if (*sssl != NULL) serverssl = *sssl; else if (!TEST_ptr(serverssl = SSL_new(serverctx))) goto error; if (*cssl != NULL) clientssl = *cssl; else if (!TEST_ptr(clientssl = SSL_new(clientctx))) goto error; if (SSL_is_dtls(clientssl)) { if (!TEST_ptr(s_to_c_bio = BIO_new(bio_s_mempacket_test())) || !TEST_ptr(c_to_s_bio = BIO_new(bio_s_mempacket_test()))) goto error; } else { if (!TEST_ptr(s_to_c_bio = BIO_new(BIO_s_mem())) || !TEST_ptr(c_to_s_bio = BIO_new(BIO_s_mem()))) goto error; } if (s_to_c_fbio != NULL && !TEST_ptr(s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio))) goto error; if (c_to_s_fbio != NULL && !TEST_ptr(c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio))) goto error; /* Set Non-blocking IO behaviour */ BIO_set_mem_eof_return(s_to_c_bio, -1); BIO_set_mem_eof_return(c_to_s_bio, -1); /* Up ref these as we are passing them to two SSL objects */ SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio); BIO_up_ref(s_to_c_bio); BIO_up_ref(c_to_s_bio); SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio); *sssl = serverssl; *cssl = clientssl; return 1; error: SSL_free(serverssl); SSL_free(clientssl); BIO_free(s_to_c_bio); BIO_free(c_to_s_bio); BIO_free(s_to_c_fbio); BIO_free(c_to_s_fbio); return 0; }
DTLSBio::DTLSBio() : _pInBIO(0), /* we use memory read bios */ _pOutBIO(0), _pSSL(0), _pSocket(0) { // // Create the bios // _pInBIO = BIO_new(BIO_s_mem()); _pOutBIO = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(_pInBIO, -1); BIO_set_mem_eof_return(_pOutBIO, -1); }
static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) { struct sockaddr_in sa; unsigned char buf[4096]; int r = 0, i; BIO *tmpout = NULL; if (out == NULL) tmpout = BIO_new(BIO_s_null()); else if (flags & CMS_TEXT) { tmpout = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(tmpout, 0); } else tmpout = out; if(!tmpout) { CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE); goto err; } /* Read all content through chain to process digest, decrypt etc */ for (;;) { i=BIO_read(in,buf,sizeof(buf)); if (i <= 0) { if (BIO_method_type(in) == BIO_TYPE_CIPHER) { if (!BIO_get_cipher_status(in)) goto err; } if (i < 0) goto err; break; } if (tmpout && (BIO_write(tmpout, buf, i, 0, sa) != i)) goto err; } if(flags & CMS_TEXT) { if(!SMIME_text(tmpout, out)) { CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR); goto err; } } r = 1; err: if (tmpout && (tmpout != out)) BIO_free(tmpout); return r; }
static PyObject * memory_bio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { BIO *bio = NULL; PySSLMemoryBIO *self = NULL; if (!PyArg_ParseTuple(args, ":MemoryBIO")) RETURN_ERROR(NULL); bio = BIO_new(BIO_s_mem()); if (bio == NULL) RETURN_ERROR("failed to allocate BIO"); /* Since our BIO is non-blocking an empty read() does not indicate EOF, * just that no data is currently available. The SSL routines should retry * the read, which we can achieve by calling BIO_set_retry_read(). */ BIO_set_retry_read(bio); BIO_set_mem_eof_return(bio, -1); self = (PySSLMemoryBIO *) type->tp_alloc(type, 0); if (self == NULL) RETURN_ERROR(NULL); self->bio = bio; bio = NULL; self->eof_written = 0; error: if (bio != NULL) BIO_free(bio); return (PyObject *) self; }
bool Parser::init() { if (!ssl) { printf("Error: dtls::Parser::init() failed because the `ssl` member hasn't been set yet.\n"); return false; } /* in bio */ { in_bio = BIO_new(BIO_s_mem()); if (!in_bio) { printf("Error: dtls::Parser::init() failed because we can't create our in_bio.\n"); return false; } BIO_set_mem_eof_return(in_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */ } /* out bio */ { out_bio = BIO_new(BIO_s_mem()); if (!out_bio) { printf("Error: dtls::Parser::init() failed because can't create out out_bio.\n"); /* @todo cleanup. */ return false; } BIO_set_mem_eof_return(out_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */ } /* set info callback */ SSL_set_info_callback(ssl, dtls_parse_ssl_info_callback); /* set in and output bios. */ SSL_set_bio(ssl, in_bio, out_bio); if (mode == DTLS_MODE_SERVER) { SSL_set_accept_state(ssl); /* in case we're a server */ } else if(mode == DTLS_MODE_CLIENT) { //SSL_set_connect_state(ssl); /* in case we're a client */ printf("dtls::Parser - error: not yet handling client state for dtls::Parser().\n"); exit(1); } return true; }
struct dtls_transport * create_dtls_transport(struct rtcdc_peer_connection *peer, const struct dtls_context *context) { if (peer == NULL || peer->transport == NULL || context == NULL || context->ctx == NULL) return NULL; struct dtls_transport *dtls = (struct dtls_transport *)calloc(1, sizeof *dtls); if (dtls == NULL) return NULL; peer->transport->dtls = dtls; SSL *ssl = SSL_new(context->ctx); if (ssl == NULL) goto trans_err; dtls->ssl = ssl; BIO *bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto trans_err; BIO_set_mem_eof_return(bio, -1); dtls->incoming_bio = bio; bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto trans_err; BIO_set_mem_eof_return(bio, -1); dtls->outgoing_bio = bio; SSL_set_bio(dtls->ssl, dtls->incoming_bio, dtls->outgoing_bio); EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); SSL_set_options(dtls->ssl, SSL_OP_SINGLE_ECDH_USE); SSL_set_tmp_ecdh(dtls->ssl, ecdh); EC_KEY_free(ecdh); if (0) { trans_err: peer->transport->dtls = NULL; SSL_free(ssl); free(dtls); dtls = NULL; } return dtls; }
BIO *BIO_mem_dummy() { static BIO *dummyBIO = NULL; if(!dummyBIO) { dummyBIO = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(dummyBIO, -1); } return dummyBIO; }
static PyObject * memory_bio_write_eof(PySSLMemoryBIO *self, PyObject *args) { self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ BIO_clear_retry_flags(self->bio); BIO_set_mem_eof_return(self->bio, 0); Py_RETURN_NONE; }
/* this sets up the SSL* */ int krx_ssl_init(krx* k, int isserver, info_callback cb) { /* create SSL* */ k->ssl = SSL_new(k->ctx); if(!k->ssl) { printf("Error: cannot create new SSL*.\n"); return -1; } /* info callback */ SSL_set_info_callback(k->ssl, cb); /* bios */ k->in_bio = BIO_new(BIO_s_mem()); if(k->in_bio == NULL) { printf("Error: cannot allocate read bio.\n"); return -2; } BIO_set_mem_eof_return(k->in_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */ k->out_bio = BIO_new(BIO_s_mem()); if(k->out_bio == NULL) { printf("Error: cannot allocate write bio.\n"); return -3; } BIO_set_mem_eof_return(k->out_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */ SSL_set_bio(k->ssl, k->in_bio, k->out_bio); /* either use the server or client part of the protocol */ if(isserver == 1) { SSL_set_accept_state(k->ssl); } else { SSL_set_connect_state(k->ssl); } return 0; }
static BIO *cms_get_text_bio(BIO *out, unsigned int flags) { BIO *rbio; if (out == NULL) rbio = BIO_new(BIO_s_null()); else if (flags & CMS_TEXT) { rbio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(rbio, 0); } else rbio = out; return rbio; }
@return: None\n\ "; static PyObject * ssl_Connection_bio_shutdown(ssl_ConnectionObj *self, PyObject *args) { if (self->from_ssl == NULL) { PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); return NULL; } BIO_set_mem_eof_return(self->into_ssl, 0); Py_INCREF(Py_None); return Py_None; }
Gzb64* gzb64_init() { int zret; Gzb64* gzb64 = (Gzb64*) malloc(sizeof(Gzb64)); if( gzb64 == NULL ) { fprintf(stderr, "Failed to malloc\n"); exit(EXIT_FAILURE); } /* Encode */ /* setup zlib encode struc */ gzb64->gz_encode_strm.zalloc = Z_NULL; gzb64->gz_encode_strm.zfree = Z_NULL; gzb64->gz_encode_strm.opaque = Z_NULL; zret = deflateInit2 (& gzb64->gz_encode_strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, windowBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY); if(zret < 0) zerr(zret); gzb64->encode_gzout_buffer = evbuffer_new(); /* setup base64 encoder */ gzb64->b64_encoder = BIO_new(BIO_f_base64()); BIO_set_flags(gzb64->b64_encoder, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer gzb64->encode_output_buffer = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(gzb64->encode_output_buffer, 0); gzb64->b64_encoder = BIO_push(gzb64->b64_encoder, gzb64->encode_output_buffer); /* Decode */ gzb64->decode_input_buffer = evbuffer_new(); /* setup base64 decoder */ gzb64->b64_decoder = BIO_new(BIO_f_base64()); BIO_set_flags(gzb64->b64_decoder, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer gzb64->decode_output_buffer = evbuffer_new(); /* setup zlib decode struc */ gzb64->gz_decode_strm.avail_in = 0; gzb64->gz_decode_strm.next_in = Z_NULL; zret = inflateInit2 (& gzb64->gz_decode_strm, windowBits | ENABLE_ZLIB_GZIP); if(zret < 0) zerr(zret); /* State */ gzb64->encoded_last_chunk = false; gzb64->decoded_last_chunk = false; return gzb64; }
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) { ASN1_OCTET_STRING **pos = CMS_get0_content(cms); if (!pos) return 0; /* If ebmedded content find memory BIO and set content */ if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { BIO *mbio; unsigned char *cont; long contlen; mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); if (!mbio) { CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); return 0; } contlen = BIO_get_mem_data(mbio, &cont); /* Set bio as read only so its content can't be clobbered */ BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(mbio, 0); ASN1_STRING_set0(*pos, cont, contlen); (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; } switch (OBJ_obj2nid(cms->contentType)) { case NID_pkcs7_data: case NID_pkcs7_enveloped: case NID_pkcs7_encrypted: case NID_id_smime_ct_compressedData: /* Nothing to do */ return 1; case NID_pkcs7_signed: return cms_SignedData_final(cms, cmsbio); case NID_pkcs7_digest: return cms_DigestedData_do_final(cms, cmsbio, 0); default: CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); return 0; } }
SSLStream::SSLStream(Stream::ptr parent, bool client, bool own, SSL_CTX *ctx) : MutatingFilterStream(parent, own) { MORDOR_ASSERT(parent); clearSSLError(); if (ctx) m_ctx.reset(ctx, &nop<SSL_CTX *>); else m_ctx.reset(SSL_CTX_new(client ? SSLv23_client_method() : SSLv23_server_method()), &SSL_CTX_free); if (!m_ctx) { MORDOR_ASSERT(hasOpenSSLError()); MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage())) // << boost::errinfo_api_function("SSL_CTX_new"); ; } // Auto-generate self-signed server cert if (!ctx && !client) { std::shared_ptr<X509> cert; std::shared_ptr<EVP_PKEY> pkey; mkcert(cert, pkey, 1024, rand(), 365); SSL_CTX_use_certificate(m_ctx.get(), cert.get()); SSL_CTX_use_PrivateKey(m_ctx.get(), pkey.get()); } m_ssl.reset(SSL_new(m_ctx.get()), &SSL_free); if (!m_ssl) { MORDOR_ASSERT(hasOpenSSLError()); MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage())) // << boost::errinfo_api_function("SSL_CTX_new"); ; } m_readBio = BIO_new(BIO_s_mem()); m_writeBio = BIO_new(BIO_s_mem()); if (!m_readBio || !m_writeBio) { if (m_readBio) BIO_free(m_readBio); if (m_writeBio) BIO_free(m_writeBio); MORDOR_ASSERT(hasOpenSSLError()); MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage())) // << boost::errinfo_api_function("BIO_new"); ; } BIO_set_mem_eof_return(m_readBio, -1); SSL_set_bio(m_ssl.get(), m_readBio, m_writeBio); }
OpenSSLCertificate* OpenSSLCertificate::FromPEMString( const std::string& pem_string, int* pem_length) { BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); if (!bio) return NULL; (void)BIO_set_close(bio, BIO_NOCLOSE); BIO_set_mem_eof_return(bio, 0); X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL, const_cast<char*>("\0")); char *ptr; int remaining_length = BIO_get_mem_data(bio, &ptr); BIO_free(bio); if (pem_length) *pem_length = pem_string.length() - remaining_length; if (x509) return new OpenSSLCertificate(x509); else return NULL; }
IoSecureSocket *IoSecureServer_dtlsWrap(IoSecureServer *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); IoSocket *sock = IoObject_getSlot_(self, IOSYMBOL("socket")); IoIPAddress *ioip = IoMessage_locals_addressArgAt_(msg, locals, 0); IPAddress *ip = IoIPAddress_rawIPAddress(ioip); struct sockaddr *addr = IPAddress_sockaddr(ip); IoNumber *port = IoObject_getSlot_(sock, IOSYMBOL("port")); int fd = IoSocket_rawDescriptor(sock); SSL *ssl = SSL_new(ctx); BIO *rbio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(rbio, -1); BIO *wbio = BIO_new_dgram(fd, BIO_NOCLOSE); BIO_dgram_set_peer(wbio, addr); SSL_set_bio(ssl, rbio, wbio); SSL_set_accept_state(ssl); set_nonblocking(wbio); SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); IoSecureSocket *ssock = IoSecureSocket_newWithSSL_IP_(IoObject_state(self), ssl, ioip); return ssock; }
void SSLStream::wantRead() { if (m_readBuffer.readAvailable() == 0) { MORDOR_LOG_TRACE(g_log) << this << " parent()->read(32768)"; const size_t result = parent()->read(m_readBuffer, 32768); MORDOR_LOG_TRACE(g_log) << this << " parent()->read(32768): " << result; if (result == 0) { BIO_set_mem_eof_return(m_readBio, 0); return; } } MORDOR_ASSERT(m_readBuffer.readAvailable()); const iovec iov = m_readBuffer.readBuffer(~0, false); MORDOR_ASSERT(iov.iov_len > 0); const int written = BIO_write(m_readBio, (char *)iov.iov_base, iov.iov_len); MORDOR_ASSERT(written > 0); if (written > 0) { m_readBuffer.consume(written); } MORDOR_LOG_DEBUG(g_log) << this << " wantRead(): " << written; }
struct sctp_transport * create_sctp_transport(struct rtcdc_peer_connection *peer) { if (peer == NULL || peer->transport == NULL) return NULL; struct sctp_transport *sctp = (struct sctp_transport *)calloc(1, sizeof *sctp); if (sctp == NULL) return NULL; peer->transport->sctp = sctp; sctp->local_port = random_integer(10000, 60000); if (g_sctp_ref == 0) { usrsctp_init(0, sctp_data_ready_cb, NULL); usrsctp_sysctl_set_sctp_ecn_enable(1); } g_sctp_ref++; usrsctp_register_address(sctp); struct socket *s = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, sctp_data_received_cb, NULL, 0, peer); if (s == NULL) goto trans_err; sctp->sock = s; BIO *bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto trans_err; BIO_set_mem_eof_return(bio, -1); sctp->incoming_bio = bio; bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto trans_err; BIO_set_mem_eof_return(bio, -1); sctp->outgoing_bio = bio; #ifdef DEBUG_SCTP int sd; struct sockaddr_in stub_addr; memset(&stub_addr, 0, sizeof stub_addr); inet_pton(AF_INET, "127.0.0.1", &stub_addr.sin_addr); stub_addr.sin_family = AF_INET; sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); stub_addr.sin_port = htons(60001); bind(sd, (const struct sockaddr *)&stub_addr, sizeof stub_addr); stub_addr.sin_port = htons(60002); connect(sd, (const struct sockaddr *)&stub_addr, sizeof stub_addr); sctp->incoming_stub = sd; sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); stub_addr.sin_port = htons(60002); bind(sd, (const struct sockaddr *)&stub_addr, sizeof stub_addr); stub_addr.sin_port = htons(60001); connect(sd, (const struct sockaddr *)&stub_addr, sizeof stub_addr); sctp->outgoing_stub = sd; #endif struct linger lopt; lopt.l_onoff = 1; lopt.l_linger = 0; usrsctp_setsockopt(s, SOL_SOCKET, SO_LINGER, &lopt, sizeof lopt); struct sctp_paddrparams peer_param; memset(&peer_param, 0, sizeof peer_param); peer_param.spp_flags = SPP_PMTUD_DISABLE; peer_param.spp_pathmtu = 1200; usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &peer_param, sizeof peer_param); struct sctp_assoc_value av; av.assoc_id = SCTP_ALL_ASSOC; av.assoc_value = 1; usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av, sizeof av); uint32_t nodelay = 1; usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, sizeof nodelay); struct sctp_initmsg init_msg; memset(&init_msg, 0, sizeof init_msg); init_msg.sinit_num_ostreams = RTCDC_MAX_OUT_STREAM; init_msg.sinit_max_instreams = RTCDC_MAX_IN_STREAM; usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, &init_msg, sizeof init_msg); struct sockaddr_conn sconn; memset(&sconn, 0, sizeof sconn); sconn.sconn_family = AF_CONN; sconn.sconn_port = htons(sctp->local_port); sconn.sconn_addr = (void *)sctp; #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) sconn.sconn_len = sizeof *sctp; #endif usrsctp_bind(s, (struct sockaddr *)&sconn, sizeof sconn); sctp->deferred_messages = g_async_queue_new(); // modified by uniray7 sctp->peer = peer; //==================== if (0) { trans_err: peer->transport->sctp = NULL; usrsctp_finish(); free(sctp); sctp = NULL; } return sctp; }
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret = 0; int i, j; BIO *btmp; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc, ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ASN1_OCTET_STRING *os = NULL; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); return 0; } EVP_MD_CTX_init(&ctx_tmp); i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_data: os = p7->d.data; break; case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk = p7->d.signed_and_enveloped->signer_info; os = p7->d.signed_and_enveloped->enc_data->enc_data; if (!os) { os = M_ASN1_OCTET_STRING_new(); if (!os) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data = os; } break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ os = p7->d.enveloped->enc_data->enc_data; if (!os) { os = M_ASN1_OCTET_STRING_new(); if (!os) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } p7->d.enveloped->enc_data->enc_data = os; } break; case NID_pkcs7_signed: si_sk = p7->d.sign->signer_info; os = PKCS7_get_octet_string(p7->d.sign->contents); /* If detached data then the content is excluded */ if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); os = NULL; p7->d.sign->contents->d.data = NULL; } break; case NID_pkcs7_digest: os = PKCS7_get_octet_string(p7->d.digest->contents); /* If detached data then the content is excluded */ if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); os = NULL; p7->d.digest->contents->d.data = NULL; } break; default: PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } if (si_sk != NULL) { for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); if (si->pkey == NULL) continue; j = OBJ_obj2nid(si->digest_alg->algorithm); btmp = bio; btmp = PKCS7_find_digest(&mdc, btmp, j); if (btmp == NULL) goto err; /* * We now have the EVP_MD_CTX, lets do the signing. */ if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) goto err; sk = si->auth_attr; /* * If there are attributes, we add the digest attribute and only * sign the attributes */ if (sk_X509_ATTRIBUTE_num(sk) > 0) { if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) goto err; } else { unsigned char *abuf = NULL; unsigned int abuflen; abuflen = EVP_PKEY_size(si->pkey); abuf = OPENSSL_malloc(abuflen); if (!abuf) goto err; if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); goto err; } ASN1_STRING_set0(si->enc_digest, abuf, abuflen); } } } else if (i == NID_pkcs7_digest) { unsigned char md_data[EVP_MAX_MD_SIZE]; unsigned int md_len; if (!PKCS7_find_digest(&mdc, bio, OBJ_obj2nid(p7->d.digest->md->algorithm))) goto err; if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) goto err; M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); } if (!PKCS7_is_detached(p7)) { /* * NOTE(emilia): I think we only reach os == NULL here because detached * digested data support is broken. */ if (os == NULL) goto err; if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { char *cont; long contlen; btmp = BIO_find_type(bio, BIO_TYPE_MEM); if (btmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } contlen = BIO_get_mem_data(btmp, &cont); /* * Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); ASN1_STRING_set0(os, (unsigned char *)cont, contlen); } } ret = 1; err: EVP_MD_CTX_cleanup(&ctx_tmp); return (ret); }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i, j; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); return NULL; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body = PKCS7_get_octet_string(p7->d.sign->contents); if (!PKCS7_is_detached(p7) && data_body == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_SIGNED_DATA_TYPE); goto err; } md_sk = p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; data_body = p7->d.enveloped->enc_data->enc_data; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } j = OBJ_obj2nid(xa->algorithm); evp_md = EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp, evp_md); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen, ivlen; int max; X509_OBJECT ret; #endif if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } /* * It was encrypted, we need to decrypt the secret key with the * private key */ /* * Find the recipientInfo which matches the passed certificate (if * any) */ if (pcert) { for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { /* * Always attempt to decrypt all rinfo even after sucess as a * defence against MMA timing attacks. */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } } else { /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) goto err; /* Generate random key as MMA defence */ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); tkey = OPENSSL_malloc(tkeylen); if (!tkey) goto err; if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) goto err; if (ek == NULL) { ek = tkey; eklen = tkeylen; tkey = NULL; } if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* * Some S/MIME clients don't use the same key and effective key * length. The key length is determined by the size of the * decrypted RSA key. */ if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { /* Use random key as MMA defence */ OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); ek = tkey; eklen = tkeylen; tkey = NULL; } } /* Clear errors so we don't leak information useful in MMA */ ERR_clear_error(); if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) goto err; if (ek) { OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); ek = NULL; } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); OPENSSL_free(tkey); tkey = NULL; } if (out == NULL) out = etmp; else BIO_push(out, etmp); etmp = NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio = in_bio; } else { # if 0 bio = BIO_new(BIO_s_mem()); /* * We need to set this so that when we have read all the data, the * encrypt BIO, if present, will read EOF and encode the last few * bytes */ BIO_set_mem_eof_return(bio, 0); if (data_body->length > 0) BIO_write(bio, (char *)data_body->data, data_body->length); # else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data, data_body->length); else { bio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio, 0); } if (bio == NULL) goto err; # endif } BIO_push(out, bio); bio = NULL; #endif if (0) { err: if (ek) { OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); OPENSSL_free(tkey); } if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out = NULL; } return (out); }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); return NULL; } /* * The content field in the PKCS7 ContentInfo is optional, but that really * only applies to inner content (precisely, detached signatures). * * When reading content, missing outer content is therefore treated as an * error. * * When creating content, PKCS7_content_new() must be called before * calling this method, so a NULL p7->d is always an error. */ if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk = p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; case NID_pkcs7_data: break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen, ivlen; EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen = EVP_CIPHER_key_length(evp_cipher); ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) if (RAND_pseudo_bytes(iv, ivlen) <= 0) goto err; if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) { xalg->parameter = ASN1_TYPE_new(); if (xalg->parameter == NULL) goto err; } if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) goto err; } OPENSSL_cleanse(key, keylen); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio = BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if (bio == NULL) { bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto err; BIO_set_mem_eof_return(bio, 0); } } if (out) BIO_push(out, bio); else out = bio; bio = NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out = NULL; } return (out); }
/* * NOTE: Transfers control of the BIOs - this function will free them on error */ int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl, SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio) { int retc = -1, rets = -1, err, abortctr = 0; int clienterr = 0, servererr = 0; SSL *serverssl, *clientssl; BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL; if (*sssl == NULL) serverssl = SSL_new(serverctx); else serverssl = *sssl; if (*cssl == NULL) clientssl = SSL_new(clientctx); else clientssl = *cssl; if (serverssl == NULL || clientssl == NULL) { printf("Failed to create SSL object\n"); goto error; } s_to_c_bio = BIO_new(BIO_s_mem()); c_to_s_bio = BIO_new(BIO_s_mem()); if (s_to_c_bio == NULL || c_to_s_bio == NULL) { printf("Failed to create mem BIOs\n"); goto error; } if (s_to_c_fbio != NULL) s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio); if (c_to_s_fbio != NULL) c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio); if (s_to_c_bio == NULL || c_to_s_bio == NULL) { printf("Failed to create chained BIOs\n"); goto error; } /* Set Non-blocking IO behaviour */ BIO_set_mem_eof_return(s_to_c_bio, -1); BIO_set_mem_eof_return(c_to_s_bio, -1); /* Up ref these as we are passing them to two SSL objects */ BIO_up_ref(s_to_c_bio); BIO_up_ref(c_to_s_bio); SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio); SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio); /* BIOs will now be freed when SSL objects are freed */ s_to_c_bio = c_to_s_bio = NULL; s_to_c_fbio = c_to_s_fbio = NULL; do { err = SSL_ERROR_WANT_WRITE; while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) { retc = SSL_connect(clientssl); if (retc <= 0) err = SSL_get_error(clientssl, retc); } if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) { printf("SSL_connect() failed %d, %d\n", retc, err); clienterr = 1; } err = SSL_ERROR_WANT_WRITE; while (!servererr && rets <= 0 && err == SSL_ERROR_WANT_WRITE) { rets = SSL_accept(serverssl); if (rets <= 0) err = SSL_get_error(serverssl, rets); } if (!servererr && rets <= 0 && err != SSL_ERROR_WANT_READ) { printf("SSL_accept() failed %d, %d\n", retc, err); servererr = 1; } if (clienterr && servererr) goto error; if (++abortctr == MAXLOOPS) { printf("No progress made\n"); goto error; } } while (retc <=0 || rets <= 0); *sssl = serverssl; *cssl = clientssl; return 1; error: if (*sssl == NULL) { SSL_free(serverssl); BIO_free(s_to_c_bio); BIO_free(s_to_c_fbio); } if (*cssl == NULL) { SSL_free(clientssl); BIO_free(c_to_s_bio); BIO_free(c_to_s_fbio); } return 0; }
int dtls_netsock_init(const STREAM_DTLS_CTXT_T *pDtlsCtxt, NETIO_SOCK_T *pnetsock, const DTLS_FINGERPRINT_VERIFY_T *pFingerprintVerify, const DTLS_KEY_UPDATE_CTXT_T *pKeysUpdateCtxt) { int rc = 0; if(!pDtlsCtxt || !pnetsock) { return -1; } if(!pnetsock || PNETIOSOCK_FD(pnetsock) == INVALID_SOCKET) { return -1; } pthread_mutex_lock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); if(pDtlsCtxt->active != 1) { pthread_mutex_unlock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); return -1; } if(!(pnetsock->ssl.pCtxt = SSL_new(pDtlsCtxt->pctx))) { LOG(X_ERROR("DTLS SSL_new failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownCtxt = 1; if(rc >= 0 && !(pnetsock->ssl.pBioRd = BIO_new(BIO_s_mem()))) { LOG(X_ERROR("DTLS BIO_new (reader) failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownBioRd = 1; if(rc >= 0 && !(pnetsock->ssl.pBioWr = BIO_new(BIO_s_mem()))) { LOG(X_ERROR("DTLS BIO_new (writer) failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownBioWr = 1; if(rc >= 0) { BIO_set_mem_eof_return(pnetsock->ssl.pBioRd, -1); BIO_set_mem_eof_return(pnetsock->ssl.pBioWr, -1); SSL_set_bio(pnetsock->ssl.pCtxt, pnetsock->ssl.pBioRd, pnetsock->ssl.pBioWr); pnetsock->ssl.ownBioRd = 0; pnetsock->ssl.ownBioWr = 0; SSL_set_mode(pnetsock->ssl.pCtxt, SSL_MODE_AUTO_RETRY); SSL_set_read_ahead(pnetsock->ssl.pCtxt, 1); //SSL_set_connect_state(pnetsock->ssl.pCtxt); //SSL_set_accept_state(pnetsock->ssl.pCtxt); if(pFingerprintVerify) { if(s_sslCbDataIndex == -1) { s_sslCbDataIndex = SSL_get_ex_new_index(0, "verifycbIndex", NULL, NULL, NULL); } SSL_set_verify(pnetsock->ssl.pCtxt, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), dtls_verify_cb); SSL_set_ex_data(pnetsock->ssl.pCtxt, s_sslCbDataIndex, (void *) pFingerprintVerify); //LOG(X_DEBUG("SSL_set_ex_data index:%d, pFingerprintVerify: 0x%x"), s_sslCbDataIndex, pFingerprintVerify); } } pnetsock->ssl.pDtlsCtxt = pDtlsCtxt; pnetsock->flags |= NETIO_FLAG_SSL_DTLS; if(pDtlsCtxt->dtls_srtp) { pnetsock->flags |= NETIO_FLAG_SRTP; if(pKeysUpdateCtxt) { memcpy(&pnetsock->ssl.dtlsKeysUpdateCtxt, pKeysUpdateCtxt, sizeof(pnetsock->ssl.dtlsKeysUpdateCtxt)); } } pthread_mutex_unlock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); return rc; }
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret=0; int i,j; BIO *btmp; BUF_MEM *buf_mem=NULL; BUF_MEM *buf=NULL; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc,ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; ASN1_OCTET_STRING *os=NULL; EVP_MD_CTX_init(&ctx_tmp); i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk=p7->d.signed_and_enveloped->signer_info; if (!(os=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data=os; break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ if (!(os=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); goto err; } p7->d.enveloped->enc_data->enc_data=os; break; case NID_pkcs7_signed: si_sk=p7->d.sign->signer_info; os=PKCS7_get_octet_string(p7->d.sign->contents); /* If detached data then the content is excluded */ if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); p7->d.sign->contents->d.data = NULL; } break; case NID_pkcs7_digest: os=PKCS7_get_octet_string(p7->d.digest->contents); /* If detached data then the content is excluded */ if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { M_ASN1_OCTET_STRING_free(os); p7->d.digest->contents->d.data = NULL; } break; } if (si_sk != NULL) { if ((buf=BUF_MEM_new()) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); goto err; } for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); if (si->pkey == NULL) continue; j=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; btmp = PKCS7_find_digest(&mdc, btmp, j); if (btmp == NULL) goto err; /* We now have the EVP_MD_CTX, lets do the * signing. */ EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); goto err; } sk=si->auth_attr; /* If there are attributes, we add the digest * attribute and only sign the attributes */ if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; unsigned int md_len, alen; ASN1_OCTET_STRING *digest; ASN1_UTCTIME *sign_time; const EVP_MD *md_tmp; /* Add signing time if not already present */ if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { if (!(sign_time=X509_gmtime_adj(NULL,0))) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, V_ASN1_UTCTIME,sign_time); } /* Add digest */ md_tmp=EVP_MD_CTX_md(&ctx_tmp); EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); if (!(digest=M_ASN1_OCTET_STRING_new())) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } if (!M_ASN1_OCTET_STRING_set(digest,md_data, md_len)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); goto err; } PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING,digest); /* Now sign the attributes */ EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if(!abuf) goto err; EVP_SignUpdate(&ctx_tmp,abuf,alen); OPENSSL_free(abuf); } #ifndef OPENSSL_NO_DSA if (si->pkey->type == EVP_PKEY_DSA) ctx_tmp.digest=EVP_dss1(); #endif #ifndef OPENSSL_NO_ECDSA if (si->pkey->type == EVP_PKEY_EC) ctx_tmp.digest=EVP_ecdsa(); #endif if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, (unsigned int *)&buf->length,si->pkey)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); goto err; } if (!ASN1_STRING_set(si->enc_digest, (unsigned char *)buf->data,buf->length)) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); goto err; } } } else if (i == NID_pkcs7_digest) { unsigned char md_data[EVP_MAX_MD_SIZE]; unsigned int md_len; if (!PKCS7_find_digest(&mdc, bio, OBJ_obj2nid(p7->d.digest->md->algorithm))) goto err; EVP_DigestFinal_ex(mdc,md_data,&md_len); M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); } if (!PKCS7_is_detached(p7)) { btmp=BIO_find_type(bio,BIO_TYPE_MEM); if (btmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } BIO_get_mem_ptr(btmp,&buf_mem); /* Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); os->data = (unsigned char *)buf_mem->data; os->length = buf_mem->length; #if 0 M_ASN1_OCTET_STRING_set(os, (unsigned char *)buf_mem->data,buf_mem->length); #endif } ret=1; err: EVP_MD_CTX_cleanup(&ctx_tmp); if (buf != NULL) BUF_MEM_free(buf); return(ret); }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; EVP_CIPHER_CTX *evp_ctx=NULL; X509_ALGOR *enc_alg=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body=PKCS7_get_octet_string(p7->d.sign->contents); md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; data_body=p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; enc_alg=p7->d.enveloped->enc_data->algorithm; data_body=p7->d.enveloped->enc_data->enc_data; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.enveloped->enc_data->algorithm; break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } j=OBJ_obj2nid(xa->algorithm); evp_md=EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen,ivlen; int max; X509_OBJECT ret; #endif int jj; if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ if (pcert) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri=NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } jj=EVP_PKEY_size(pkey); tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj > 0) break; ERR_clear_error(); ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY); goto err; } } else { jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto err; } } evp_ctx=NULL; BIO_get_cipher_ctx(etmp,&evp_ctx); if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) goto err; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } } if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) goto err; OPENSSL_cleanse(tmp,jj); if (out == NULL) out=etmp; else BIO_push(out,etmp); etmp=NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio=in_bio; } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; #endif if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out=NULL; } if (tmp != NULL) OPENSSL_free(tmp); return(out); }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; ASN1_OCTET_STRING *os=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk=p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; xalg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; xalg=p7->d.enveloped->enc_data->algorithm; evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; int jj,max; unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) xalg->parameter=ASN1_TYPE_new(); if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ max=0; for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (ri->cert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); goto err; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); OPENSSL_free(tmp); goto err; } if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); goto err; } } OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } BIO_push(out,bio); bio=NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out=NULL; } return(out); }
void BIO_set_mem_eof_return_shim(BIO *b, int v) { BIO_set_mem_eof_return(b, v); }
unsigned int OpenSSLCryptoKeyRSA::signSHA1PKCS1Base64Signature(unsigned char * hashBuf, unsigned int hashLen, char * base64SignatureBuf, unsigned int base64SignatureBufLen, hashMethod hm) { // Sign a pre-calculated hash using this key if (mp_rsaKey == NULL) { throw XSECCryptoException(XSECCryptoException::RSAError, "OpenSSL:RSA - Attempt to sign data with empty key"); } // Build the buffer to be encrypted by prepending the SHA1 OID to the hash unsigned char * encryptBuf; unsigned char * preEncryptBuf; unsigned char * oid; int oidLen; int encryptLen; int preEncryptLen; oid = getRSASigOID(hm, oidLen); if (oid == NULL) { throw XSECCryptoException(XSECCryptoException::RSAError, "OpenSSL:RSA::sign() - Unsupported HASH algorithm for RSA"); } if (hashLen != oid[oidLen-1]) { throw XSECCryptoException(XSECCryptoException::RSAError, "OpenSSL:RSA::sign() - hashLen incorrect for hash type"); } preEncryptLen = hashLen + oidLen; preEncryptBuf = new unsigned char[preEncryptLen]; encryptBuf = new unsigned char[RSA_size(mp_rsaKey)]; memcpy(preEncryptBuf, oid, oidLen); memcpy(&preEncryptBuf[oidLen], hashBuf, hashLen); // Now encrypt encryptLen = RSA_private_encrypt(preEncryptLen, preEncryptBuf, encryptBuf, mp_rsaKey, RSA_PKCS1_PADDING); delete[] preEncryptBuf; if (encryptLen < 0) { delete[] encryptBuf; throw XSECCryptoException(XSECCryptoException::RSAError, "OpenSSL:RSA::sign() - Error encrypting hash"); } // Now convert to Base 64 BIO * b64 = BIO_new(BIO_f_base64()); BIO * bmem = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bmem, 0); b64 = BIO_push(b64, bmem); // Translate signature to Base64 BIO_write(b64, encryptBuf, encryptLen); BIO_flush(b64); unsigned int sigValLen = BIO_read(bmem, base64SignatureBuf, base64SignatureBufLen); BIO_free_all(b64); delete[] encryptBuf; if (sigValLen <= 0) { throw XSECCryptoException(XSECCryptoException::DSAError, "OpenSSL:RSA - Error base64 encoding signature"); } return sigValLen; }