BOOL freerdp_tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) { int status; UINT32 option_value; socklen_t option_len; if (!hostname) return FALSE; if (hostname[0] == '/') tcp->ipcSocket = TRUE; if (tcp->ipcSocket) { tcp->sockfd = uds_connect(hostname); if (tcp->sockfd < 0) return FALSE; tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) return FALSE; BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } else { #ifdef HAVE_POLL_H struct pollfd pollfds; #else fd_set cfds; struct timeval tv; #endif #ifdef NO_IPV6 tcp->socketBio = BIO_new(BIO_s_connect()); if (!tcp->socketBio) return FALSE; if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0) return FALSE; BIO_set_nbio(tcp->socketBio, 1); status = BIO_do_connect(tcp->socketBio); if ((status <= 0) && !BIO_should_retry(tcp->socketBio)) return FALSE; tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL); if (tcp->sockfd < 0) return FALSE; #else /* NO_IPV6 */ struct addrinfo hints = {0}; struct addrinfo *result; struct addrinfo *tmp; char port_str[11]; //ZeroMemory(&hints, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* * FIXME: the following is a nasty workaround. Find a cleaner way: * Either set port manually afterwards or get it passed as string? */ sprintf_s(port_str, 11, "%u", port); status = getaddrinfo(hostname, port_str, &hints, &result); if (status) { WLog_ERR(TAG, "getaddrinfo: %s", gai_strerror(status)); return FALSE; } /* For now prefer IPv4 over IPv6. */ tmp = result; if (tmp->ai_family == AF_INET6 && tmp->ai_next != 0) { while ((tmp = tmp->ai_next)) { if (tmp->ai_family == AF_INET) break; } if (!tmp) tmp = result; } tcp->sockfd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); if (tcp->sockfd < 0) { freeaddrinfo(result); return FALSE; } if (connect(tcp->sockfd, tmp->ai_addr, tmp->ai_addrlen) < 0) { WLog_ERR(TAG, "connect: %s", strerror(errno)); freeaddrinfo(result); return FALSE; } freeaddrinfo(result); tcp->socketBio = BIO_new_socket(tcp->sockfd, BIO_NOCLOSE); /* TODO: make sure the handshake is done by querying the bio */ // if (BIO_should_retry(tcp->socketBio)) // return FALSE; #endif /* NO_IPV6 */ if (status <= 0) { #ifdef HAVE_POLL_H pollfds.fd = tcp->sockfd; pollfds.events = POLLOUT; pollfds.revents = 0; do { status = poll(&pollfds, 1, timeout * 1000); } while ((status < 0) && (errno == EINTR)); #else FD_ZERO(&cfds); FD_SET(tcp->sockfd, &cfds); tv.tv_sec = timeout; tv.tv_usec = 0; status = _select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv); #endif if (status == 0) { return FALSE; /* timeout */ } } (void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE); BIO_free(tcp->socketBio); tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) return FALSE; BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } SetEventFileDescriptor(tcp->event, tcp->sockfd); freerdp_tcp_get_ip_address(tcp); freerdp_tcp_get_mac_address(tcp); option_value = 1; option_len = sizeof(option_value); if (!tcp->ipcSocket) { if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0) WLog_ERR(TAG, "unable to set TCP_NODELAY"); } /* receive buffer must be a least 32 K */ if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0) { if (option_value < (1024 * 32)) { option_value = 1024 * 32; option_len = sizeof(option_value); if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0) { WLog_ERR(TAG, "unable to set receive buffer len"); return FALSE; } } } if (!tcp->ipcSocket) { if (!freerdp_tcp_set_keep_alive_mode(tcp)) return FALSE; } tcp->bufferedBio = BIO_new(BIO_s_buffered_socket()); if (!tcp->bufferedBio) return FALSE; tcp->bufferedBio->ptr = tcp; tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio); return TRUE; }
/* Return value: * SSL_OK: the SSL handle is created * SSL_ERROR: failed, call ossSSLERRGetError() & ossSSLERRGetErrorMessage() for reason */ INT32 ossSSLNewHandle(SSLHandle** handle, SSLContext* ctx, SOCKET sock, const char* initialBytes, INT32 len) { SSLHandle* h = NULL; SSL* ssl = NULL; BIO* bufferBIO = NULL; BIO* socketBIO = NULL; INT32 ret = SSL_OK; SSL_ASSERT(NULL != handle); SSL_ASSERT(NULL != ctx); SSL_ASSERT(len >= 0); h = (SSLHandle*)OPENSSL_malloc(sizeof(SSLHandle)); if (NULL == h) { goto error; } _SSLHandleInit(h); h->sock = sock; ssl = SSL_new(ctx); if (NULL == ssl) { goto error; } h->ssl = ssl; if (0 == len) { /* there is no initial bytes, so we just set the socket to SSL */ ret = SSL_set_fd(ssl, sock); if (!ret) { goto error; } } else /* len > 0 */ { SSL_ASSERT(NULL != initialBytes); /* * There are initial SSL bytes, so we should give these bytes to SSL by some way. * Here we create a buffer BIO, and put these bytes to it. * Then we create a socket BIO, and set a BIO chain to link * the buffer and socket by BIO_push(). * Finally, we set the buffer to SSL instead of the socket. * * NOTE: when do SSL operations, it should explicitly flush the buffer. */ bufferBIO = BIO_new(BIO_f_buffer()); if (NULL == bufferBIO) { goto error; } ret = BIO_set_buffer_read_data(bufferBIO, (void*)initialBytes, len); if (!ret) { goto error; } socketBIO = BIO_new_socket(sock, BIO_NOCLOSE); if (NULL == socketBIO) { goto error; } /* link socket to the buffer */ if (NULL == BIO_push(bufferBIO, socketBIO)) { goto error; } /* SSL_free() will also free bufferBIO, * so it's no need to free bufferBIO later when free the SSL handle. */ SSL_set_bio(ssl, bufferBIO, bufferBIO); /* hold the bufferBIO pointer so we can flush it when do SSL operations */ h->bufferBIO = bufferBIO; } *handle = h; ret = SDB_OK; done: return ret; error: if (NULL != bufferBIO) { BIO_free(bufferBIO); } if (NULL != socketBIO) { BIO_free(socketBIO); } if (NULL != ssl) { SSL_free(ssl); } if (NULL != h) { OPENSSL_free(h); } ret = SSL_ERROR; goto done; }
void output_cert_info(X509 *cert, gf_io_t pc) { char buf[256]; STORE_S *left,*right; gf_io_t spc; int len; left = so_get(CharStar, NULL, EDIT_ACCESS); right = so_get(CharStar, NULL, EDIT_ACCESS); if(!(left && right)) return; gf_set_so_writec(&spc, left); if(!cert->cert_info){ gf_puts("Couldn't find certificate info.", spc); gf_puts(NEWLINE, spc); } else{ gf_puts_uline("Subject (whose certificate it is)", spc); gf_puts(NEWLINE, spc); output_X509_NAME(cert->cert_info->subject, spc); gf_puts(NEWLINE, spc); gf_puts_uline("Serial Number", spc); gf_puts(NEWLINE, spc); snprintf(buf, sizeof(buf), "%ld", ASN1_INTEGER_get(cert->cert_info->serialNumber)); gf_puts(buf, spc); gf_puts(NEWLINE, spc); gf_puts(NEWLINE, spc); gf_puts_uline("Validity", spc); gf_puts(NEWLINE, spc); { BIO *mb = BIO_new(BIO_s_mem()); char iobuf[4096]; gf_puts("Not Before: ", spc); (void) BIO_reset(mb); ASN1_UTCTIME_print(mb, cert->cert_info->validity->notBefore); (void) BIO_flush(mb); while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) gf_nputs(iobuf, len, spc); gf_puts(NEWLINE, spc); gf_puts("Not After: ", spc); (void) BIO_reset(mb); ASN1_UTCTIME_print(mb, cert->cert_info->validity->notAfter); (void) BIO_flush(mb); while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) gf_nputs(iobuf, len, spc); gf_puts(NEWLINE, spc); gf_puts(NEWLINE, spc); BIO_free(mb); } } gf_clear_so_writec(left); gf_set_so_writec(&spc, right); if(!cert->cert_info){ gf_puts(_("Couldn't find certificate info."), spc); gf_puts(NEWLINE, spc); } else{ gf_puts_uline("Issuer", spc); gf_puts(NEWLINE, spc); output_X509_NAME(cert->cert_info->issuer, spc); gf_puts(NEWLINE, spc); } gf_clear_so_writec(right); side_by_side(left, right, pc); gf_puts_uline("SHA1 Fingerprint", pc); gf_puts(NEWLINE, pc); get_fingerprint(cert, EVP_sha1(), buf, sizeof(buf)); gf_puts(buf, pc); gf_puts(NEWLINE, pc); gf_puts_uline("MD5 Fingerprint", pc); gf_puts(NEWLINE, pc); get_fingerprint(cert, EVP_md5(), buf, sizeof(buf)); gf_puts(buf, pc); gf_puts(NEWLINE, pc); so_give(&left); so_give(&right); }
int main(int Argc, char *ARGV[]) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; FUNCTION f,*fp; MS_STATIC const char *prompt; MS_STATIC char buf[1024]; char *to_free=NULL; int n,i,ret=0; int argc; char **argv,*p; LHASH_OF(FUNCTION) *prog=NULL; long errline; #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) /* 2011-03-22 SMS. * If we have 32-bit pointers everywhere, then we're safe, and * we bypass this mess, as on non-VMS systems. (See ARGV, * above.) * Problem 1: Compaq/HP C before V7.3 always used 32-bit * pointers for argv[]. * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers * everywhere else, we always allocate and use a 64-bit * duplicate of argv[]. * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed * to NULL-terminate a 64-bit argv[]. (As this was written, the * compiler ECO was available only on IA64.) * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a * 64-bit argv[argc] for NULL, and, if necessary, use a * (properly) NULL-terminated (64-bit) duplicate of argv[]. * The same code is used in either case to duplicate argv[]. * Some of these decisions could be handled in preprocessing, * but the code tends to get even uglier, and the penalty for * deciding at compile- or run-time is tiny. */ char **Argv = NULL; int free_Argv = 0; if ((sizeof( _Argv) < 8) /* 32-bit argv[]. */ # if !defined( VMS_TRUST_ARGV) || (_Argv[ Argc] != NULL) /* Untrusted argv[argc] not NULL. */ # endif ) { int i; Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *)); if (Argv == NULL) { ret = -1; goto end; } for(i = 0; i < Argc; i++) Argv[i] = _Argv[i]; Argv[ Argc] = NULL; /* Certain NULL termination. */ free_Argv = 1; } else { /* Use the known-good 32-bit argv[] (which needs the * type cast to satisfy the compiler), or the trusted or * tested-good 64-bit argv[] as-is. */ Argv = (char **)_Argv; } #endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */ arg.data=NULL; arg.count=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */ { if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #if 0 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) #endif { CRYPTO_set_locking_callback(lock_dbg_cb); } if(getenv("OPENSSL_FIPS")) { #ifdef OPENSSL_FIPS if (!FIPS_mode_set(1)) { ERR_load_crypto_strings(); ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); EXIT(1); } #else fprintf(stderr, "FIPS mode not supported.\n"); EXIT(1); #endif } apps_startup(); /* Lets load up our environment a little */ p=getenv("OPENSSL_CONF"); if (p == NULL) p=getenv("SSLEAY_CONF"); if (p == NULL) p=to_free=make_config_name(); default_config_file=p; config=NCONF_new(NULL); i=NCONF_load(config,p,&errline); if (i == 0) { if (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE) { BIO_printf(bio_err, "WARNING: can't open config file: %s\n",p); ERR_clear_error(); NCONF_free(config); config = NULL; } else { ERR_print_errors(bio_err); NCONF_free(config); exit(1); } } prog=prog_init(); /* first check the program name */ program_name(Argv[0],pname,sizeof pname); f.name=pname; fp=lh_FUNCTION_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; ret=fp->func(Argc,Argv); goto end; } /* ok, now check that there are not arguments, if there are, * run with them, shifting the ssleay off the front */ if (Argc != 1) { Argc--; Argv++; ret=do_cmd(prog,Argc,Argv); if (ret < 0) ret=0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret=0; p=buf; n=sizeof buf; i=0; for (;;) { p[0]='\0'; if (i++) prompt=">"; else prompt="OpenSSL> "; fputs(prompt,stdout); fflush(stdout); if (!fgets(p,n,stdin)) goto end; if (p[0] == '\0') goto end; i=strlen(p); if (i <= 1) break; if (p[i-2] != '\\') break; i-=2; p+=i; n-=i; } if (!chopup_args(&arg,buf,&argc,&argv)) break; ret=do_cmd(prog,argc,argv); if (ret < 0) { ret=0; goto end; } if (ret != 0) BIO_printf(bio_err,"error in %s\n",argv[0]); (void)BIO_flush(bio_err); } BIO_printf(bio_err,"bad exit\n"); ret=1; end: if (to_free) OPENSSL_free(to_free); if (config != NULL) { NCONF_free(config); config=NULL; } if (prog != NULL) lh_FUNCTION_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { BIO_free(bio_err); bio_err=NULL; } #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) /* Free any duplicate Argv[] storage. */ if (free_Argv) { OPENSSL_free(Argv); } #endif OPENSSL_EXIT(ret); }
static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) { int *ip; long ret = 1; BIO_ACCEPT *data; char **pp; data = (BIO_ACCEPT *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ret = 0; data->state = ACPT_S_BEFORE; acpt_close_socket(b); b->flags = 0; break; case BIO_C_DO_STATE_MACHINE: /* use this one to start the connection */ ret = (long)acpt_state(b, data); break; case BIO_C_SET_ACCEPT: if (ptr != NULL) { if (num == 0) { b->init = 1; free(data->param_addr); data->param_addr = strdup(ptr); } else if (num == 1) { data->accept_nbio = (ptr != NULL); } else if (num == 2) { BIO_free(data->bio_chain); data->bio_chain = (BIO *)ptr; } } break; case BIO_C_SET_NBIO: data->nbio = (int)num; break; case BIO_C_SET_FD: b->init = 1; b->num = *((int *)ptr); data->accept_sock = b->num; data->state = ACPT_S_GET_ACCEPT_SOCKET; b->shutdown = (int)num; b->init = 1; break; case BIO_C_GET_FD: if (b->init) { ip = (int *)ptr; if (ip != NULL) *ip = data->accept_sock; ret = data->accept_sock; } else ret = -1; break; case BIO_C_GET_ACCEPT: if (b->init) { if (ptr != NULL) { pp = (char **)ptr; *pp = data->param_addr; } else ret = -1; } else ret = -1; break; case BIO_CTRL_GET_CLOSE: ret = b->shutdown; break; case BIO_CTRL_SET_CLOSE: b->shutdown = (int)num; break; case BIO_CTRL_PENDING: case BIO_CTRL_WPENDING: ret = 0; break; case BIO_CTRL_FLUSH: break; case BIO_C_SET_BIND_MODE: data->bind_mode = (int)num; break; case BIO_C_GET_BIND_MODE: ret = (long)data->bind_mode; break; case BIO_CTRL_DUP: /* dbio=(BIO *)ptr; if (data->param_port) EAY EAY BIO_set_port(dbio,data->param_port); if (data->param_hostname) BIO_set_hostname(dbio,data->param_hostname); BIO_set_nbio(dbio,data->nbio); */ break; default: ret = 0; break; } return (ret); }
int main(int Argc, char *Argv[]) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; FUNCTION f,*fp; MS_STATIC const char *prompt; MS_STATIC char buf[1024]; char *to_free=NULL; int n,i,ret=0; int argc; char **argv,*p; LHASH *prog=NULL; long errline; arg.data=NULL; arg.count=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */ { if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #if 0 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) #endif { CRYPTO_set_locking_callback(lock_dbg_cb); } apps_startup(); /* Lets load up our environment a little */ p=getenv("OPENSSL_CONF"); if (p == NULL) p=getenv("SSLEAY_CONF"); if (p == NULL) p=to_free=make_config_name(); default_config_file=p; config=NCONF_new(NULL); i=NCONF_load(config,p,&errline); if (i == 0) { NCONF_free(config); config = NULL; ERR_clear_error(); } prog=prog_init(); /* first check the program name */ program_name(Argv[0],pname,sizeof pname); f.name=pname; fp=(FUNCTION *)lh_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; ret=fp->func(Argc,Argv); goto end; } /* ok, now check that there are not arguments, if there are, * run with them, shifting the ssleay off the front */ if (Argc != 1) { Argc--; Argv++; ret=do_cmd(prog,Argc,Argv); if (ret < 0) ret=0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret=0; p=buf; n=sizeof buf; i=0; for (;;) { p[0]='\0'; if (i++) prompt=">"; else prompt="OpenSSL> "; fputs(prompt,stdout); fflush(stdout); fgets(p,n,stdin); if (p[0] == '\0') goto end; i=strlen(p); if (i <= 1) break; if (p[i-2] != '\\') break; i-=2; p+=i; n-=i; } if (!chopup_args(&arg,buf,&argc,&argv)) break; ret=do_cmd(prog,argc,argv); if (ret < 0) { ret=0; goto end; } if (ret != 0) BIO_printf(bio_err,"error in %s\n",argv[0]); (void)BIO_flush(bio_err); } BIO_printf(bio_err,"bad exit\n"); ret=1; end: if (to_free) OPENSSL_free(to_free); if (config != NULL) { NCONF_free(config); config=NULL; } if (prog != NULL) lh_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { BIO_free(bio_err); bio_err=NULL; } OPENSSL_EXIT(ret); return ret; }
static DWORD VMCAGetX509Name( X509_NAME* pCertName, DWORD dwFlags, PSTR* ppszSubjectName ) { DWORD dwError = 0; int length = 0; BIO* pBioMem = NULL; PSTR pszSubjectName = NULL; pBioMem = BIO_new(BIO_s_mem()); if (!pBioMem) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_ERROR(dwError); } X509_NAME_print_ex(pBioMem, pCertName, 0, dwFlags); length = BIO_pending(pBioMem); if (length <= 0) { dwError = ERROR_INVALID_DATA; BAIL_ON_ERROR(dwError); } dwError = VMCAAllocateMemory((DWORD)(length + 1), (PVOID*)&pszSubjectName); BAIL_ON_ERROR(dwError); if (BIO_read(pBioMem, pszSubjectName, length) != length) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } *ppszSubjectName = pszSubjectName; cleanup: if (pBioMem) { BIO_free(pBioMem); } return dwError; error: if (ppszSubjectName) { *ppszSubjectName = NULL; } VMCA_SAFE_FREE_MEMORY(pszSubjectName); goto cleanup; }
int main(int argc, char *argv[]) { char *port = NULL; BIO *in = NULL; BIO *ssl_bio, *tmp; SSL_CTX *ctx; char buf[512]; int ret = 1, i; if (argc <= 1) port = "*:4433"; else port = argv[1]; SSL_load_error_strings(); /* Add ciphers and message digests */ OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(TLS_server_method()); if (!SSL_CTX_use_certificate_chain_file(ctx, CERT_FILE)) goto err; if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) goto err; if (!SSL_CTX_check_private_key(ctx)) goto err; /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); /* Arrange to leave server loop on interrupt */ sigsetup(); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; while (!done) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) goto err; fwrite(buf, 1, i, stdout); fflush(stdout); } ret = 0; err: if (ret) { ERR_print_errors_fp(stderr); } BIO_free(in); exit(ret); return (!ret); }
//-------------------------------------------------------------------------------------------------- le_result_t secSocket_AddCertificate ( secSocket_Ctx_t* ctxPtr, ///< [INOUT] Secure socket context pointer const uint8_t* certificatePtr, ///< [IN] Certificate Pointer size_t certificateLen ///< [IN] Certificate Length ) { X509_STORE *store = NULL; X509 *cert = NULL; BIO *bio = NULL; le_result_t status = LE_FAULT; le_clk_Time_t currentTime; // Check input parameters if ((!ctxPtr) || (!certificatePtr) || (!certificateLen)) { return LE_BAD_PARAMETER; } OpensslCtx_t* contextPtr = GetContext(ctxPtr); if (!contextPtr) { return LE_BAD_PARAMETER; } LE_INFO("Certificate: %p Len:%zu", certificatePtr, certificateLen); // Get a BIO abstraction pointer bio = BIO_new_mem_buf((void*)certificatePtr, certificateLen); if (!bio) { LE_ERROR("Unable to allocate BIO pointer"); goto end; } // Read the DER formatted certificate from memory into an X509 structure cert = d2i_X509(NULL, &certificatePtr, certificateLen); if (!cert) { LE_ERROR("Unable to read certificate"); goto end; } // Check certificate validity currentTime = le_clk_GetAbsoluteTime(); if ((X509_cmp_time(X509_get_notBefore(cert), ¤tTime.sec) >= 0) || (X509_cmp_time(X509_get_notAfter(cert), ¤tTime.sec) <= 0)) { LE_ERROR("Current certificate expired, please add a valid certificate"); status = LE_FORMAT_ERROR; goto end; } // Get a pointer to the current certificate verification pool store = SSL_CTX_get_cert_store(contextPtr->sslCtxPtr); if (!store) { LE_ERROR("Unable to get a pointer to the X509 certificate"); goto end; } // Add certificate to the verification pool if (!X509_STORE_add_cert(store, cert)) { LE_ERROR("Unable to add certificate to pool"); goto end; } status = LE_OK; end: if (cert) { X509_free(cert); } if (bio) { BIO_free(bio); } return status; }
extern "C" int32_t BioDestroy(BIO* a) { return BIO_free(a); }
int tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, struct tls_keypair *keypair, int required) { EVP_PKEY *pkey = NULL; X509 *cert = NULL; BIO *bio = NULL; if (!required && keypair->cert_mem == NULL && keypair->key_mem == NULL && keypair->cert_file == NULL && keypair->key_file == NULL) return(0); if (keypair->cert_mem != NULL) { if (keypair->cert_len > INT_MAX) { tls_set_errorx(ctx, "certificate too long"); goto err; } if (SSL_CTX_use_certificate_chain_mem(ssl_ctx, keypair->cert_mem, keypair->cert_len) != 1) { tls_set_errorx(ctx, "failed to load certificate"); goto err; } cert = NULL; } if (keypair->key_mem != NULL) { if (keypair->key_len > INT_MAX) { tls_set_errorx(ctx, "key too long"); goto err; } if ((bio = BIO_new_mem_buf(keypair->key_mem, keypair->key_len)) == NULL) { tls_set_errorx(ctx, "failed to create buffer"); goto err; } if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)) == NULL) { tls_set_errorx(ctx, "failed to read private key"); goto err; } if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { tls_set_errorx(ctx, "failed to load private key"); goto err; } BIO_free(bio); bio = NULL; EVP_PKEY_free(pkey); pkey = NULL; } if (keypair->cert_file != NULL) { if (SSL_CTX_use_certificate_chain_file(ssl_ctx, keypair->cert_file) != 1) { tls_set_errorx(ctx, "failed to load certificate file"); goto err; } } if (keypair->key_file != NULL) { if (SSL_CTX_use_PrivateKey_file(ssl_ctx, keypair->key_file, SSL_FILETYPE_PEM) != 1) { tls_set_errorx(ctx, "failed to load private key file"); goto err; } } if (SSL_CTX_check_private_key(ssl_ctx) != 1) { tls_set_errorx(ctx, "private/public key mismatch"); goto err; } return (0); err: EVP_PKEY_free(pkey); X509_free(cert); BIO_free(bio); return (1); }
int main (int argc, char **argv) { BIO *in = NULL, *out = NULL, *tbio = NULL; X509 *scert = NULL; EVP_PKEY *skey = NULL; CMS_ContentInfo *cms = NULL; int ret = 1; /* For simple S/MIME signing use CMS_DETACHED. * On OpenSSL 1.0.0 only: * for streaming detached set CMS_DETACHED|CMS_STREAM * for streaming non-detached set CMS_STREAM */ int flags = CMS_DETACHED | CMS_STREAM; OpenSSL_add_all_algorithms (); ERR_load_crypto_strings (); /* Read in signer certificate and private key */ tbio = BIO_new_file ("signer.pem", "r"); if (!tbio) goto err; scert = PEM_read_bio_X509 (tbio, NULL, 0, NULL); BIO_reset (tbio); skey = PEM_read_bio_PrivateKey (tbio, NULL, 0, NULL); if (!scert || !skey) goto err; /* Open content being signed */ in = BIO_new_file ("sign.txt", "r"); if (!in) goto err; /* Sign content */ cms = CMS_sign (scert, skey, NULL, in, flags); if (!cms) goto err; out = BIO_new_file ("smout.txt", "w"); if (!out) goto err; if (!(flags & CMS_STREAM)) BIO_reset (in); /* Write out S/MIME message */ if (!SMIME_write_CMS (out, cms, in, flags)) goto err; ret = 0; err: if (ret) { fprintf (stderr, "Error Signing Data\n"); ERR_print_errors_fp (stderr); } if (cms) CMS_ContentInfo_free (cms); if (scert) X509_free (scert); if (skey) EVP_PKEY_free (skey); if (in) BIO_free (in); if (out) BIO_free (out); if (tbio) BIO_free (tbio); return ret; }
int pkey_main(int argc, char **argv) { ENGINE *e = NULL; char **args, *infile = NULL, *outfile = NULL; char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int informat, outformat; int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; EVP_PKEY *pkey = NULL; char *passin = NULL, *passout = NULL; int badarg = 0; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif int ret = 1; informat = FORMAT_PEM; outformat = FORMAT_PEM; args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-passin")) { if (!args[1]) goto bad; passargin = *(++args); } else if (!strcmp(*args, "-passout")) { if (!args[1]) goto bad; passargout = *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args, "-engine") == 0) { if (!args[1]) goto bad; engine = *(++args); } #endif else if (!strcmp(*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (strcmp(*args, "-pubin") == 0) { pubin = 1; pubout = 1; pubtext = 1; } else if (strcmp(*args, "-pubout") == 0) pubout = 1; else if (strcmp(*args, "-text_pub") == 0) { pubtext = 1; text = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else if (strcmp(*args, "-noout") == 0) noout = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } } args++; } if (badarg) { bad: BIO_printf(bio_err, "Usage pkey [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif return 1; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } if (pubin) pkey = load_pubkey(bio_err, infile, informat, 1, passin, e, "Public Key"); else pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!noout) { if (outformat == FORMAT_PEM) { if (pubout) PEM_write_bio_PUBKEY(out, pkey); else PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout); } else if (outformat == FORMAT_ASN1) { if (pubout) i2d_PUBKEY_bio(out, pkey); else i2d_PrivateKey_bio(out, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } } if (text) { if (pubtext) EVP_PKEY_print_public(out, pkey, 0, NULL); else EVP_PKEY_print_private(out, pkey, 0, NULL); } ret = 0; end: EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); free(passin); free(passout); return ret; }
int pkcs7_main(int argc, char **argv) { ENGINE *e = NULL; PKCS7 *p7 = NULL; BIO *in = NULL, *out = NULL; int informat = FORMAT_PEM, outformat = FORMAT_PEM; char *infile = NULL, *outfile = NULL, *prog; int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; OPTION_CHOICE o; prog = opt_init(argc, argv, pkcs7_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(pkcs7_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_NOOUT: noout = 1; break; case OPT_TEXT: text = 1; break; case OPT_PRINT: p7_print = 1; break; case OPT_PRINT_CERTS: print_certs = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); if (argc != 0) goto opthelp; in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); if (p7 == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (p7_print) PKCS7_print_ctx(out, p7, 0, NULL); if (print_certs) { STACK_OF(X509) *certs = NULL; STACK_OF(X509_CRL) *crls = NULL; i = OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: if (p7->d.sign != NULL) { certs = p7->d.sign->cert; crls = p7->d.sign->crl; } break; case NID_pkcs7_signedAndEnveloped: if (p7->d.signed_and_enveloped != NULL) { certs = p7->d.signed_and_enveloped->cert; crls = p7->d.signed_and_enveloped->crl; } break; default: break; } if (certs != NULL) { X509 *x; for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); if (text) X509_print(out, x); else dump_cert_text(out, x); if (!noout) PEM_write_bio_X509(out, x); BIO_puts(out, "\n"); } } if (crls != NULL) { X509_CRL *crl; for (i = 0; i < sk_X509_CRL_num(crls); i++) { crl = sk_X509_CRL_value(crls, i); X509_CRL_print(out, crl); if (!noout) PEM_write_bio_X509_CRL(out, crl); BIO_puts(out, "\n"); } } ret = 0; goto end; } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else i = PEM_write_bio_PKCS7(out, p7); if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: PKCS7_free(p7); release_engine(e); BIO_free(in); BIO_free_all(out); return (ret); }
int main(int argc, char **argv) { BIO *sbio = NULL, *out = NULL; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL_CONF_CTX *cctx; SSL *ssl; char **args = argv + 1; const char *connect_str = "localhost:4433"; int nargs = argc - 1; ERR_load_crypto_strings(); ERR_load_SSL_strings(); SSL_library_init(); ctx = SSL_CTX_new(TLS_client_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); while (*args && **args == '-') { int rv; /* Parse standard arguments */ rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); if (rv == -3) { fprintf(stderr, "Missing argument for %s\n", *args); goto end; } if (rv < 0) { fprintf(stderr, "Error in command %s\n", *args); ERR_print_errors_fp(stderr); goto end; } /* If rv > 0 we processed something so proceed to next arg */ if (rv > 0) continue; /* Otherwise application specific argument processing */ if (strcmp(*args, "-connect") == 0) { connect_str = args[1]; if (connect_str == NULL) { fprintf(stderr, "Missing -connect argument\n"); goto end; } args += 2; nargs -= 2; continue; } else { fprintf(stderr, "Unknown argument %s\n", *args); goto end; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto end; } /* * We'd normally set some stuff like the verify paths and * mode here * because as things stand this will connect to * any server whose * certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto end; } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, connect_str); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); goto end; } if (BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); goto end; } /* Could examine ssl here to get connection info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } end: SSL_CONF_CTX_free(cctx); BIO_free_all(sbio); BIO_free(out); return 0; }
int main(int argc, char *argv[]) { BN_CTX *ctx; BIO *out = NULL; int i, ret; unsigned char c; BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m; RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we * don't even check its return * value (which we should) */ ERR_load_BN_strings(); ctx = BN_CTX_new(); if (ctx == NULL) EXIT(1); r_mont = BN_new(); r_mont_const = BN_new(); r_recp = BN_new(); r_simple = BN_new(); a = BN_new(); b = BN_new(); m = BN_new(); if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL)) goto err; out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE); for (i = 0; i < 200; i++) { RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(a, NUM_BITS + c, 0, 0); RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(b, NUM_BITS + c, 0, 0); RAND_bytes(&c, 1); c = (c % BN_BITS) - BN_BITS2; BN_rand(m, NUM_BITS + c, 0, 1); BN_mod(a, a, m, ctx); BN_mod(b, b, m, ctx); ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL); if (ret <= 0) { printf("BN_mod_exp_mont() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_recp(r_recp, a, b, m, ctx); if (ret <= 0) { printf("BN_mod_exp_recp() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_simple(r_simple, a, b, m, ctx); if (ret <= 0) { printf("BN_mod_exp_simple() problems\n"); ERR_print_errors(out); EXIT(1); } ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL); if (ret <= 0) { printf("BN_mod_exp_mont_consttime() problems\n"); ERR_print_errors(out); EXIT(1); } if (BN_cmp(r_simple, r_mont) == 0 && BN_cmp(r_simple, r_recp) == 0 && BN_cmp(r_simple, r_mont_const) == 0) { printf("."); fflush(stdout); } else { if (BN_cmp(r_simple, r_mont) != 0) printf("\nsimple and mont results differ\n"); if (BN_cmp(r_simple, r_mont_const) != 0) printf("\nsimple and mont const time results differ\n"); if (BN_cmp(r_simple, r_recp) != 0) printf("\nsimple and recp results differ\n"); printf("a (%3d) = ", BN_num_bits(a)); BN_print(out, a); printf("\nb (%3d) = ", BN_num_bits(b)); BN_print(out, b); printf("\nm (%3d) = ", BN_num_bits(m)); BN_print(out, m); printf("\nsimple ="); BN_print(out, r_simple); printf("\nrecp ="); BN_print(out, r_recp); printf("\nmont ="); BN_print(out, r_mont); printf("\nmont_ct ="); BN_print(out, r_mont_const); printf("\n"); EXIT(1); } } BN_free(r_mont); BN_free(r_mont_const); BN_free(r_recp); BN_free(r_simple); BN_free(a); BN_free(b); BN_free(m); BN_CTX_free(ctx); ERR_remove_thread_state(NULL); CRYPTO_mem_leaks(out); BIO_free(out); printf("\n"); if (test_exp_mod_zero() != 0) goto err; printf("done\n"); EXIT(0); err: ERR_load_crypto_strings(); ERR_print_errors(out); #ifdef OPENSSL_SYS_NETWARE printf("ERROR\n"); #endif EXIT(1); return (1); }
int main(int argc, char **argv) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE + 1]; FUNCTION f, *fp; const char *prompt; char buf[1024]; char *to_free = NULL; int n, i, ret = 0; char *p; LHASH_OF(FUNCTION) * prog = NULL; long errline; arg.data = NULL; arg.count = 0; if (pledge("stdio inet dns rpath wpath cpath proc flock tty", NULL) == -1) { fprintf(stderr, "openssl: pledge: %s\n", strerror(errno)); exit(1); } bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (bio_err == NULL) { fprintf(stderr, "openssl: failed to initialise bio_err\n"); exit(1); } if (BIO_sock_init() != 1) { BIO_printf(bio_err, "BIO_sock_init failed\n"); exit(1); } CRYPTO_set_locking_callback(lock_dbg_cb); openssl_startup(); /* Lets load up our environment a little */ p = getenv("OPENSSL_CONF"); if (p == NULL) { p = to_free = make_config_name(); if (p == NULL) { BIO_printf(bio_err, "error making config file name\n"); goto end; } } default_config_file = p; config = NCONF_new(NULL); i = NCONF_load(config, p, &errline); if (i == 0) { if (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE) { BIO_printf(bio_err, "WARNING: can't open config file: %s\n", p); ERR_clear_error(); NCONF_free(config); config = NULL; } else { ERR_print_errors(bio_err); NCONF_free(config); exit(1); } } if (!load_config(bio_err, NULL)) { BIO_printf(bio_err, "failed to load configuration\n"); goto end; } prog = prog_init(); /* first check the program name */ program_name(argv[0], pname, sizeof pname); f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); if (fp != NULL) { argv[0] = pname; single_execution = 1; ret = fp->func(argc, argv); goto end; } /* * ok, now check that there are not arguments, if there are, run with * them, shifting the ssleay off the front */ if (argc != 1) { argc--; argv++; single_execution = 1; ret = do_cmd(prog, argc, argv); if (ret < 0) ret = 0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret = 0; p = buf; n = sizeof buf; i = 0; for (;;) { p[0] = '\0'; if (i++) prompt = ">"; else prompt = "OpenSSL> "; fputs(prompt, stdout); fflush(stdout); if (!fgets(p, n, stdin)) goto end; if (p[0] == '\0') goto end; i = strlen(p); if (i <= 1) break; if (p[i - 2] != '\\') break; i -= 2; p += i; n -= i; } if (!chopup_args(&arg, buf, &argc, &argv)) break; ret = do_cmd(prog, argc, argv); if (ret < 0) { ret = 0; goto end; } if (ret != 0) BIO_printf(bio_err, "error in %s\n", argv[0]); (void) BIO_flush(bio_err); } BIO_printf(bio_err, "bad exit\n"); ret = 1; end: free(to_free); if (config != NULL) { NCONF_free(config); config = NULL; } if (prog != NULL) lh_FUNCTION_free(prog); free(arg.data); openssl_shutdown(); if (bio_err != NULL) { BIO_free(bio_err); bio_err = NULL; } return (ret); }
static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { int to_return = 1; switch(cmd) { case HWCRHK_CMD_SO_PATH: if(hwcrhk_dso) { HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED); return 0; } if(p == NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER); return 0; } return set_HWCRHK_LIBNAME((const char *)p); case ENGINE_CTRL_SET_LOGSTREAM: { BIO *bio = (BIO *)p; CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if (logstream) { BIO_free(logstream); logstream = NULL; } if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) logstream = bio; else HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED); } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_PASSWORD_CALLBACK: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.password_callback = (pem_password_cb *)f; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_USER_INTERFACE: case HWCRHK_CMD_SET_USER_INTERFACE: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.ui_method = (UI_METHOD *)p; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_CALLBACK_DATA: case HWCRHK_CMD_SET_CALLBACK_DATA: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.callback_data = p; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* this enables or disables the "SimpleForkCheck" flag used in the * initialisation structure. */ case ENGINE_CTRL_CHIL_SET_FORKCHECK: case HWCRHK_CMD_FORK_CHECK: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(i) hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; else hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* This will prevent the initialisation function from "installing" * the mutex-handling callbacks, even if they are available from * within the library (or were provided to the library from the * calling application). This is to remove any baggage for * applications not using multithreading. */ case ENGINE_CTRL_CHIL_NO_LOCKING: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); disable_mutex_callbacks = 1; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case HWCRHK_CMD_THREAD_LOCKING: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); disable_mutex_callbacks = ((i == 0) ? 0 : 1); CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* The command isn't understood by this engine */ default: HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); to_return = 0; break; } return to_return; }
int main(int argc, char *argv[]) { int r, c, long_optind = 0; sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; sc_file_t *file = NULL; sc_path_t path; RSA *rsa = NULL; BIGNUM *bn = NULL; BIO *mem = NULL; static const char *pin = NULL; static const char *puk = NULL; while (1) { c = getopt_long(argc, argv, "r:wgol:ix:y:nut:fj:k:hv", \ options, &long_optind); if (c == -1) break; if (c == '?' || c == 'h') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 'r': opt_reader = optarg; break; case 'w': opt_wait = 1; break; case 'g': if(keylen == 0) keylen = 1536; break; case 'o': overwrite = 1; break; case 'l': keylen = atoi(optarg); break; case 'i': install_pin = 1; break; case 'x': util_get_pin(optarg, &pin); break; case 'y': util_get_pin(optarg, &puk); break; case 'n': new_pin = 1; break; case 'u': unlock = 1; break; case 't': cert = optarg; break; case 'f': finalize = 1; break; case 'j': get_filename = optarg; break; case 'k': put_filename = optarg; break; case 'v': verbose++; break; } } memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = argv[0]; r = sc_context_create(&ctx, &ctx_param); if (r) { printf("Failed to establish context: %s\n", sc_strerror(r)); return 1; } if (verbose > 1) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } if (opt_driver != NULL) { r = sc_set_card_driver(ctx, opt_driver); if (r) { printf("Driver '%s' not found!\n", opt_driver); goto out; } } r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); if (r) goto out; sc_format_path("3F00", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; if(install_pin) { sc_format_path("AAAA", &path); r = sc_select_file(card, &path, NULL); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; file = sc_file_new(); if(file == NULL) { printf("Not enough memory.\n"); goto out; } file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->shareable = 0; file->id = 0xAAAA; file->size = 37; r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_NONE, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_NONE, 0); if(r) goto out; /* sc_format_path("3F00AAAA", &(file->path)); */ file->path = path; r = sc_create_file(card, file); if(r) goto out; } if(pin != NULL) { sc_changekey_t ck; struct sc_pin_cmd_pin pin_cmd; int ret; memset(&pin_cmd, 0, sizeof(pin_cmd)); memset(&ck, 0, sizeof(ck)); memcpy(ck.key_template, "\x1e\x00\x00\x10", 4); pin_cmd.encoding = SC_PIN_ENCODING_GLP; pin_cmd.len = strlen(pin); pin_cmd.data = (u8*)pin; pin_cmd.max_length = 8; ret = sc_build_pin(ck.new_key.key_value, sizeof(ck.new_key.key_value), &pin_cmd, 1); if(ret < 0) goto out; ck.new_key.key_len = ret; r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); if(r) goto out; } if(puk != NULL) { sc_changekey_t ck; struct sc_pin_cmd_pin puk_cmd; int ret; memset(&puk_cmd, 0, sizeof(puk_cmd)); memset(&ck, 0, sizeof(ck)); memcpy(ck.key_template, "\x1e\x00\x00\x20", 4); puk_cmd.encoding = SC_PIN_ENCODING_GLP; puk_cmd.len = strlen(puk); puk_cmd.data = (u8*)puk; puk_cmd.max_length = 8; ret = sc_build_pin(ck.new_key.key_value, sizeof(ck.new_key.key_value), &puk_cmd, 1); if(ret < 0) goto out; ck.new_key.key_len = ret; r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); if(r) goto out; } } if(new_pin) { if(change_pin(card, 0, pin, puk)) printf("Wrong pin.\n"); goto out; } if(unlock) { if(unlock_pin(card, 0, puk, pin)) printf("Error unblocking pin.\n"); goto out; } printf("verify pin.\n"); { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); goto out; } } if(keylen) { size_t lg; struct sc_pkcs15_pubkey key; struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa); u8 *pdata; memset(&key, 0, sizeof(key)); key.algorithm = SC_ALGORITHM_RSA; printf("Generate key of length %d.\n", keylen); rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); if(rsa == NULL || bn == NULL || mem == NULL) { printf("Not enough memory.\n"); goto out; } if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, keylen, bn, NULL)) { printf("RSA_generate_key_ex return %ld\n", ERR_get_error()); goto out; } RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); if(!i2d_RSAPrivateKey_bio(mem, rsa)) { printf("i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error()); goto out; } lg = BIO_get_mem_data(mem, &pdata); sc_format_path("0001", &path); r = sc_select_file(card, &path, NULL); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; file = sc_file_new(); if(file == NULL) { printf("Not enough memory.\n"); goto out; } file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->shareable = 0; file->size = ((lg/4)+1)*4; r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_CHV, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0); if(r) goto out; file->path = path; printf("File key creation %s, size %"SC_FORMAT_LEN_SIZE_T"d.\n", file->path.value, file->size); r = sc_create_file(card, file); if(r) goto out; } else { if(!overwrite) { printf("Key file already exist,"\ " use -o to replace it.\n"); goto out; } } printf("Private key length is %"SC_FORMAT_LEN_SIZE_T"d\n", lg); printf("Write private key.\n"); r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Private key correctly written.\n"); r = create_file_cert(card); if(r) goto out; { const BIGNUM *rsa_n, *rsa_e; RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); if (!do_convert_bignum(&dst->modulus, rsa_n) || !do_convert_bignum(&dst->exponent, rsa_e)) goto out; } r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); if(r) goto out; printf("Public key length %"SC_FORMAT_LEN_SIZE_T"d\n", lg); sc_format_path("3F000002", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; printf("Write public key.\n"); r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Public key correctly written.\n"); } if(cert) { BIO *bio; X509 *xp; u8 *pdata; bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, cert) <= 0) { BIO_free(bio); printf("Can't open file %s.\n", cert); goto out; } xp = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (xp == NULL) { print_openssl_error(); goto out; } else { int lg = cert2der(xp, &pdata); sc_format_path("0002", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; /* FIXME: verify if the file has a compatible size... */ printf("Write certificate %s.\n", cert); r = sc_update_binary(card,0,pdata,lg,0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); } else { r = sc_update_binary(card,0,pdata,lg,0); } } if(r<0) { if(pdata) free(pdata); goto out; } if(xp) X509_free(xp); if(pdata) free(pdata); printf("Certificate correctly written.\n"); } } if(finalize) { int mode = SC_CARDCTRL_LIFECYCLE_USER; if(card->atr.value[10] != 0x82) { sc_format_path("0001", &path); r = sc_select_file(card, &path, NULL); if(r) { printf("This card don't have private key"\ " and can't be finalize.\n"); goto out; } printf("Finalize card...\n"); if(sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL) || sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &mode)) { printf("Error finalizing card,"\ " card isn't secure.\n"); goto out; } } printf("Card correctly finalized.\n"); } if(get_filename) { FILE *fp; u8 *b; if(file) { sc_file_free(file); file = NULL; } sc_format_path(get_filename, &path); r = sc_select_file(card, &path, &file); if(r) { printf("Error file not found.\n"); goto out; } b = malloc(file->size); if(b == NULL) { printf("Not enough memory.\n"); goto out; } r = sc_read_binary(card, 0, b, file->size, 0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); goto out; } r = sc_read_binary(card, 0, b, file->size, 0); } if(r<0) { printf("Error reading file.\n"); goto out; } fp = fopen(get_filename, "wb"); fwrite(b, 1, file->size, fp); fclose(fp); free(b); } if(put_filename) { FILE *fp; u8 *b; if(file) { sc_file_free(file); file = NULL; } sc_format_path(put_filename, &path); r = sc_select_file(card, &path, &file); if(r) { printf("File not found.\n"); goto out; } b = malloc(file->size); if(b == NULL) { printf("Not enough memory.\n"); goto out; } memset(b, 0, file->size); fp = fopen(put_filename, "rb"); if (fp == NULL || file->size != fread(b, 1, file->size, fp)) { printf("could not read %s.\n", put_filename); goto out; } fclose(fp); r = sc_update_binary(card, 0, b, file->size, 0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); } else { r = sc_update_binary(card, 0, b, file->size, 0); } } if(r<0) { free(b); printf("Error writing file.\n"); goto out; } free(b); } out: if(mem) BIO_free(mem); if(bn) BN_free(bn); if(rsa) RSA_free(rsa); if(file) sc_file_free(file); if (card) { sc_unlock(card); sc_disconnect_card(card); } sc_release_context(ctx); return EXIT_SUCCESS; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL; char *signerfile = NULL, *recipfile = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; const EVP_CIPHER *cipher = NULL; PKCS7 *p7 = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; int badarg = 0; int flags = PKCS7_DETACHED; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-pk7out")) operation = SMIME_PK7OUT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-text")) flags |= PKCS7_TEXT; else if (!strcmp (*args, "-nointern")) flags |= PKCS7_NOINTERN; else if (!strcmp (*args, "-noverify")) flags |= PKCS7_NOVERIFY; else if (!strcmp (*args, "-nochain")) flags |= PKCS7_NOCHAIN; else if (!strcmp (*args, "-nocerts")) flags |= PKCS7_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= PKCS7_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~PKCS7_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= PKCS7_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; else if (!strcmp (*args, "-nooldmime")) flags |= PKCS7_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= PKCS7_CRLFEOL; else if (!strcmp(*args,"-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } #endif else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp (*args, "-to")) { if (args[1]) { args++; to = *args; } else badarg = 1; } else if (!strcmp (*args, "-from")) { if (args[1]) { args++; from = *args; } else badarg = 1; } else if (!strcmp (*args, "-subject")) { if (args[1]) { args++; subject = *args; } else badarg = 1; } else if (!strcmp (*args, "-signer")) { if (args[1]) { args++; signerfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-recip")) { if (args[1]) { args++; recipfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-keyform")) { if (args[1]) { args++; keyform = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-content")) { if (args[1]) { args++; contfile = *args; } else badarg = 1; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else badarg = 1; args++; } if (operation == SMIME_SIGN) { if (!signerfile) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-pk7out output PKCS#7 structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (operation != SMIME_SIGN) flags &= ~PKCS7_DETACHED; if (operation & SMIME_OP) { if (flags & PKCS7_BINARY) inmode = "rb"; if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & PKCS7_BINARY) outmode = "wb"; if (informat == FORMAT_ASN1) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message is already printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args); #endif goto end; } sk_X509_push(encerts, cert); cert = NULL; args++; } } if (signerfile && (operation == SMIME_SIGN)) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL, e, "signer certificate"))) { #if 0 /* An appropri message has already been printed */ BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); #endif goto end; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { #if 0 /* An appropriate message has already been printed */ BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); #endif ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message has alrady been printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); #endif ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if (operation == SMIME_SIGN) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (operation == SMIME_VERIFY) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb_func(store, smime_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) p7 = PKCS7_encrypt(encerts, in, cipher, flags); else if (operation == SMIME_SIGN) { /* If detached data and SMIME output enable partial * signing. */ if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) flags |= PKCS7_STREAM; p7 = PKCS7_sign(signer, key, other, in, flags); } else { if (informat == FORMAT_SMIME) p7 = SMIME_read_PKCS7(in, &indata); else if (informat == FORMAT_PEM) p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } if (!p7) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } } if (!p7) { BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (!PKCS7_decrypt(p7, key, recip, out, flags)) { BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); goto end; } } else if (operation == SMIME_VERIFY) { STACK_OF(X509) *signers; if (PKCS7_verify(p7, other, store, indata, out, flags)) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } signers = PKCS7_get0_signers(p7, other, flags); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } else if (operation == SMIME_PK7OUT) PEM_write_bio_PKCS7(out, p7); else { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) SMIME_write_PKCS7(out, p7, in, flags); else if (outformat == FORMAT_PEM) PEM_write_bio_PKCS7(out,p7); else if (outformat == FORMAT_ASN1) i2d_PKCS7_bio(out,p7); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); PKCS7_free(p7); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int port) { int match; int index; char* common_name = NULL; int common_name_length = 0; char** alt_names = NULL; int alt_names_count = 0; int* alt_names_lengths = NULL; BOOL certificate_status; BOOL hostname_match = FALSE; BOOL verification_status = FALSE; rdpCertificateData* certificate_data; if (tls->settings->ExternalCertificateManagement) { BIO* bio; int status; int length; int offset; BYTE* pemCert; freerdp* instance = (freerdp*) tls->settings->instance; /** * Don't manage certificates internally, leave it up entirely to the external client implementation */ bio = BIO_new(BIO_s_mem()); if (!bio) { WLog_ERR(TAG, "BIO_new() failure"); return -1; } status = PEM_write_bio_X509(bio, cert->px509); if (status < 0) { WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status); return -1; } offset = 0; length = 2048; pemCert = (BYTE*) malloc(length + 1); status = BIO_read(bio, pemCert, length); if (status < 0) { WLog_ERR(TAG, "failed to read certificate"); return -1; } offset += status; while (offset >= length) { length *= 2; pemCert = (BYTE*) realloc(pemCert, length + 1); status = BIO_read(bio, &pemCert[offset], length); if (status < 0) break; offset += status; } if (status < 0) { WLog_ERR(TAG, "failed to read certificate"); return -1; } length = offset; pemCert[length] = '\0'; status = -1; if (instance->VerifyX509Certificate) { status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); } WLog_ERR(TAG, "(length = %d) status: %d%s", length, status, pemCert); free(pemCert); BIO_free(bio); if (status < 0) return -1; return (status == 0) ? 0 : 1; } /* ignore certificate verification if user explicitly required it (discouraged) */ if (tls->settings->IgnoreCertificate) return 1; /* success! */ /* if user explicitly specified a certificate name, use it instead of the hostname */ if (tls->settings->CertificateName) hostname = tls->settings->CertificateName; /* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */ certificate_status = x509_verify_certificate(cert, tls->certificate_store->path); /* verify certificate name match */ certificate_data = crypto_get_certificate_data(cert->px509, hostname); /* extra common name and alternative names */ common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length); alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count, &alt_names_lengths); /* compare against common name */ if (common_name) { if (tls_match_hostname(common_name, common_name_length, hostname)) hostname_match = TRUE; } /* compare against alternative names */ if (alt_names) { for (index = 0; index < alt_names_count; index++) { if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname)) { hostname_match = TRUE; break; } } } /* if the certificate is valid and the certificate name matches, verification succeeds */ if (certificate_status && hostname_match) { if (common_name) { free(common_name); common_name = NULL; } verification_status = TRUE; /* success! */ } /* if the certificate is valid but the certificate name does not match, warn user, do not accept */ if (certificate_status && !hostname_match) tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); /* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */ if (!certificate_status) { char* issuer; char* subject; char* fingerprint; freerdp* instance = (freerdp*) tls->settings->instance; BOOL accept_certificate = FALSE; issuer = crypto_cert_issuer(cert->px509); subject = crypto_cert_subject(cert->px509); fingerprint = crypto_cert_fingerprint(cert->px509); /* search for matching entry in known_hosts file */ match = certificate_data_match(tls->certificate_store, certificate_data); if (match == 1) { /* no entry was found in known_hosts file, prompt user for manual verification */ if (!hostname_match) tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); if (instance->VerifyCertificate) { accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint); } if (!accept_certificate) { /* user did not accept, abort and do not add entry in known_hosts file */ verification_status = FALSE; /* failure! */ } else { /* user accepted certificate, add entry in known_hosts file */ certificate_data_print(tls->certificate_store, certificate_data); verification_status = TRUE; /* success! */ } } else if (match == -1) { /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file); if (instance->VerifyChangedCertificate) { accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, ""); } if (!accept_certificate) { /* user did not accept, abort and do not change known_hosts file */ verification_status = FALSE; /* failure! */ } else { /* user accepted new certificate, add replace fingerprint for this host in known_hosts file */ certificate_data_replace(tls->certificate_store, certificate_data); verification_status = TRUE; /* success! */ } } else if (match == 0) { verification_status = TRUE; /* success! */ } free(issuer); free(subject); free(fingerprint); } if (certificate_data) { free(certificate_data->fingerprint); free(certificate_data->hostname); free(certificate_data); } #ifndef _WIN32 if (common_name) free(common_name); #endif if (alt_names) crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths, alt_names); return (verification_status == 0) ? 0 : 1; }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec = NULL; VALUE arg, pass; VALUE group = Qnil; char *passwd = NULL; GetPKey(self, pkey); if (pkey->pkey.ec) ossl_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { ec = EC_KEY_new(); } else { if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); ec = EC_KEY_dup(other_ec); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = EC_KEY_new(); group = arg; } else { BIO *in = ossl_obj2bio(arg); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); if (!ec) { OSSL_BIO_reset(in); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (ec == NULL) { const char *name = StringValueCStr(arg); int nid = OBJ_sn2nid(name); (void)ERR_get_error(); if (nid == NID_undef) ossl_raise(eECError, "unknown curve name (%s)\n", name); if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL) ossl_raise(eECError, "unable to create curve (%s)\n", name); EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } } } if (ec == NULL) ossl_raise(eECError, NULL); if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); if (!NIL_P(group)) rb_funcall(self, rb_intern("group="), 1, arg); return self; }
static int acpt_state(BIO *b, BIO_ACCEPT *c) { BIO *bio = NULL, *dbio; int s = -1; int i; again: switch (c->state) { case ACPT_S_BEFORE: if (c->param_addr == NULL) { BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED); return (-1); } s = BIO_get_accept_socket(c->param_addr, c->bind_mode); if (s == INVALID_SOCKET) return (-1); if (c->accept_nbio) { if (!BIO_socket_nbio(s, 1)) { close(s); BIOerr(BIO_F_ACPT_STATE, BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET); return (-1); } } c->accept_sock = s; b->num = s; c->state = ACPT_S_GET_ACCEPT_SOCKET; return (1); /* break; */ case ACPT_S_GET_ACCEPT_SOCKET: if (b->next_bio != NULL) { c->state = ACPT_S_OK; goto again; } BIO_clear_retry_flags(b); b->retry_reason = 0; i = BIO_accept(c->accept_sock, &(c->addr)); /* -2 return means we should retry */ if (i == -2) { BIO_set_retry_special(b); b->retry_reason = BIO_RR_ACCEPT; return -1; } if (i < 0) return (i); bio = BIO_new_socket(i, BIO_CLOSE); if (bio == NULL) goto err; BIO_set_callback(bio, BIO_get_callback(b)); BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); if (c->nbio) { if (!BIO_socket_nbio(i, 1)) { BIOerr(BIO_F_ACPT_STATE, BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); goto err; } } /* If the accept BIO has an bio_chain, we dup it and * put the new socket at the end. */ if (c->bio_chain != NULL) { if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) goto err; if (!BIO_push(dbio, bio)) goto err; bio = dbio; } if (BIO_push(b, bio) == NULL) goto err; c->state = ACPT_S_OK; return (1); err: BIO_free(bio); if (s >= 0) close(s); return (0); /* break; */ case ACPT_S_OK: if (b->next_bio == NULL) { c->state = ACPT_S_GET_ACCEPT_SOCKET; goto again; } return (1); /* break; */ default: return (0); /* break; */ } }
static void bio_cleanup (void) { if (in) BIO_free(in); }
PKI_X509_OCSP_REQ * ocspd_req_get_socket ( int connfd, OCSPD_CONFIG *ocspd_conf) { PKI_X509_OCSP_REQ *req = NULL; PKI_X509_OCSP_REQ_VALUE *req_val = NULL; PKI_IO *mem = NULL; PKI_MEM *pathmem = NULL; PKI_SOCKET sock; size_t maxsize = 0; maxsize = (size_t) ocspd_conf->max_req_size; PKI_HTTP *http_msg = NULL; if ( connfd <= 0 ) return NULL; // Initialize the sock structure sock.ssl = NULL; PKI_SOCKET_set_fd ( &sock, connfd ); http_msg = PKI_HTTP_get_message(&sock, (int) ocspd_conf->max_timeout_secs, maxsize); if (http_msg == NULL) { PKI_log_err ("Network Error while reading Request!"); return NULL; } /* If method is METHOD_GET we shall de-urlify the buffer and get the right begin (keep in mind there might be a path set in the config */ if( http_msg->method == PKI_HTTP_METHOD_GET ) { char *req_pnt = NULL; if (http_msg->path == NULL) { PKI_log_err("Malformed GET request"); goto err; } req_pnt = http_msg->path; while(strchr(req_pnt, '/') != NULL) { req_pnt = strchr(req_pnt, '/') + 1; } pathmem = PKI_MEM_new_data(strlen(req_pnt), (unsigned char *) req_pnt); if (pathmem == NULL) { PKI_log_err("Memory Allocation Error!"); goto err; } if (PKI_MEM_decode(pathmem, PKI_DATA_FORMAT_URL, 0) != PKI_OK) { PKI_log_err("Memory Allocation Error!"); PKI_MEM_free(pathmem); goto err; } if (PKI_MEM_decode(pathmem, PKI_DATA_FORMAT_B64, 0) != PKI_OK) { PKI_log_err ("Error decoding B64 Mem"); PKI_MEM_free (pathmem); goto err; } // Generates a new mem bio from the pathmem if((mem = BIO_new_mem_buf(pathmem->data, (int) pathmem->size)) == NULL) { PKI_log_err("Memory Allocation Error"); PKI_MEM_free(pathmem); goto err; } // Transfer data ownership and release the pathmem pathmem->data = NULL; pathmem->size = 0; // Tries to decode the binary (der) encoded request if ((req_val = d2i_OCSP_REQ_bio(mem, NULL)) == NULL) { PKI_log_err("Can not parse REQ"); BIO_free(mem); PKI_MEM_free(pathmem); goto err; } // Let's free the mem BIO_free(mem); PKI_MEM_free(pathmem); } else if (http_msg->method == PKI_HTTP_METHOD_POST) { mem = BIO_new_mem_buf(http_msg->body->data, (int) http_msg->body->size); if (mem == NULL) { PKI_log_err( "Memory Allocation Error"); goto err; } else { if ((req_val = d2i_OCSP_REQ_bio(mem, NULL)) == NULL) { PKI_log_err("Can not parse REQ"); } BIO_free (mem); } } else { PKI_log_err ( "HTTP Method not supported"); goto err; } if ( !req_val ) goto err; req = PKI_X509_new_value(PKI_DATATYPE_X509_OCSP_REQ, req_val, NULL); if (req == NULL) { PKI_log_err ("Can not generate a new X509_OCSP_REQ"); goto err; } if ( http_msg ) PKI_HTTP_free ( http_msg ); return (req); err: if (req) PKI_X509_OCSP_REQ_free(req); if (http_msg) PKI_HTTP_free(http_msg); return NULL; }
static int get_raw_key_from_file (int type, u_int8_t *id, size_t id_len, RSA **rsa) { char filename[FILENAME_MAX]; char *fstr; struct stat st; BIO *bio; if (type != IKE_AUTH_RSA_SIG) /* XXX More types? */ { LOG_DBG ((LOG_NEGOTIATION, 20, "get_raw_key_from_file: " "invalid auth type %d\n", type)); return -1; } *rsa = 0; fstr = conf_get_str ("General", "Pubkey-directory"); if (!fstr) fstr = CONF_DFLT_PUBKEY_DIR; if (snprintf (filename, sizeof filename, "%s/", fstr) > sizeof filename - 1) return -1; fstr = ipsec_id_string (id, id_len); if (!fstr) { LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: " "ipsec_id_string failed")); return -1; } strlcat (filename, fstr, sizeof filename - strlen (filename)); free (fstr); /* If the file does not exist, fail silently. */ if (stat (filename, &st) == 0) { bio = BIO_new (BIO_s_file ()); if (!bio) { log_error ("get_raw_key_from_file: could not initialize BIO"); return -1; } if (BIO_read_filename (bio, filename) <= 0) { LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: " "BIO_read_filename(bio, \"%s\") failed", filename)); BIO_free (bio); return -1; } LOG_DBG ((LOG_NEGOTIATION, 80, "get_raw_key_from_file: reading file %s", filename)); *rsa = PEM_read_bio_RSA_PUBKEY (bio, NULL, NULL, NULL); BIO_free (bio); } else LOG_DBG ((LOG_NEGOTIATION, 50, "get_raw_key_from_file: file %s not found", filename)); return (*rsa ? 0 : -1); }
int main(int argc, char **argv) { BIO *in = NULL, *out = NULL, *tbio = NULL; X509 *rcert = NULL; STACK_OF(X509) *recips = NULL; CMS_ContentInfo *cms = NULL; int ret = 1; /* * On OpenSSL 1.0.0 and later only: * for streaming set CMS_STREAM */ int flags = CMS_STREAM; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* Read in recipient certificate */ tbio = BIO_new_file("signer.pem", "r"); if (!tbio) goto err; rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); if (!rcert) goto err; /* Create recipient STACK and add recipient cert to it */ recips = sk_X509_new_null(); if (!recips || !sk_X509_push(recips, rcert)) goto err; /* * sk_X509_pop_free will free up recipient STACK and its contents so set * rcert to NULL so it isn't freed up twice. */ rcert = NULL; /* Open content being encrypted */ in = BIO_new_file("encr.txt", "r"); if (!in) goto err; /* encrypt content */ cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags); if (!cms) goto err; out = BIO_new_file("smencr.txt", "w"); if (!out) goto err; /* Write out S/MIME message */ if (!SMIME_write_CMS(out, cms, in, flags)) goto err; ret = 0; err: if (ret) { fprintf(stderr, "Error Encrypting Data\n"); ERR_print_errors_fp(stderr); } CMS_ContentInfo_free(cms); X509_free(rcert); sk_X509_pop_free(recips, X509_free); BIO_free(in); BIO_free(out); BIO_free(tbio); return ret; }
/* * Find and decode the configured key (pre-shared or public) for the * peer denoted by ID. Stash the len in KEYLEN. */ static void * ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen) { char *key, *buf; #if defined (USE_X509) || defined (USE_KEYNOTE) char *keyfile; #if defined (USE_X509) BIO *keyh; RSA *rsakey; size_t fsize; #endif #endif switch (type) { case IKE_AUTH_PRE_SHARED: /* Get the pre-shared key for our peer. */ key = conf_get_str (id, "Authentication"); if (!key && local_id) key = conf_get_str (local_id, "Authentication"); if (!key) { log_print ("ike_auth_get_key: " "no key found for peer \"%s\" or local ID \"%s\"", id, local_id); return 0; } /* If the key starts with 0x it is in hex format. */ if (strncasecmp (key, "0x", 2) == 0) { *keylen = (strlen (key) - 1) / 2; buf = malloc (*keylen); if (!buf) { log_print ("ike_auth_get_key: malloc (%lu) failed", (unsigned long)*keylen); return 0; } if (hex2raw (key + 2, (unsigned char *)buf, *keylen)) { free (buf); log_print ("ike_auth_get_key: invalid hex key %s", key); return 0; } key = buf; } else *keylen = strlen (key); break; case IKE_AUTH_RSA_SIG: #if defined (USE_X509) || defined (USE_KEYNOTE) #if defined (USE_KEYNOTE) if (local_id && (keyfile = conf_get_str ("KeyNote", "Credential-directory")) != 0) { struct stat sb; struct keynote_deckey dc; char *privkeyfile, *buf2; int fd, pkflen; size_t size; pkflen = strlen (keyfile) + strlen (local_id) + sizeof PRIVATE_KEY_FILE + sizeof "//" - 1; privkeyfile = calloc (pkflen, sizeof (char)); if (!privkeyfile) { log_print ("ike_auth_get_key: failed to allocate %d bytes", pkflen); return 0; } snprintf (privkeyfile, pkflen, "%s/%s/%s", keyfile, local_id, PRIVATE_KEY_FILE); keyfile = privkeyfile; if (stat (keyfile, &sb) < 0) { free (keyfile); goto ignorekeynote; } size = (size_t)sb.st_size; fd = open (keyfile, O_RDONLY, 0); if (fd < 0) { log_print ("ike_auth_get_key: failed opening \"%s\"", keyfile); free (keyfile); return 0; } buf = calloc (size + 1, sizeof (char)); if (!buf) { log_print ("ike_auth_get_key: failed allocating %lu bytes", (unsigned long)size + 1); free (keyfile); return 0; } if (read (fd, buf, size) != size) { free (buf); log_print ("ike_auth_get_key: " "failed reading %lu bytes from \"%s\"", (unsigned long)size, keyfile); free (keyfile); return 0; } close (fd); /* Parse private key string */ buf2 = kn_get_string (buf); free (buf); if (kn_decode_key (&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1) { free (buf2); log_print ("ike_auth_get_key: failed decoding key in \"%s\"", keyfile); free (keyfile); return 0; } free (buf2); if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA) { log_print ("ike_auth_get_key: wrong algorithm type %d in \"%s\"", dc.dec_algorithm, keyfile); free (keyfile); kn_free_key (&dc); return 0; } free (keyfile); return dc.dec_key; } ignorekeynote: #endif /* USE_KEYNOTE */ #ifdef USE_X509 /* Otherwise, try X.509 */ keyfile = conf_get_str ("X509-certificates", "Private-key"); if (check_file_secrecy (keyfile, &fsize)) return 0; keyh = BIO_new (BIO_s_file ()); if (keyh == NULL) { log_print ("ike_auth_get_key: " "BIO_new (BIO_s_file ()) failed"); return 0; } if (BIO_read_filename (keyh, keyfile) == -1) { log_print ("ike_auth_get_key: " "BIO_read_filename (keyh, \"%s\") failed", keyfile); BIO_free (keyh); return 0; } #if SSLEAY_VERSION_NUMBER >= 0x00904100L rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL); #else rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL); #endif BIO_free (keyh); if (!rsakey) { log_print ("ike_auth_get_key: PEM_read_bio_RSAPrivateKey failed"); return 0; } return rsakey; #endif /* USE_X509 */ #endif /* USE_X509 || USE_KEYNOTE */ default: log_print ("ike_auth_get_key: unknown key type %d", type); return 0; } return key; }
int MAIN(int argc, char **argv) { int i, badops = 0, offset = 0, ret = 1, j; unsigned int length = 0; long num, tmplen; BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL; int informat, indent = 0, noout = 0, dump = 0; char *infile = NULL, *str = NULL, *prog, *oidfile = NULL, *derfile = NULL; char *genstr = NULL, *genconf = NULL; unsigned char *tmpbuf; const unsigned char *ctmpbuf; BUF_MEM *buf = NULL; STACK_OF(OPENSSL_STRING) *osk = NULL; ASN1_TYPE *at = NULL; informat = FORMAT_PEM; apps_startup(); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; prog = argv[0]; argc--; argv++; if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); goto end; } while (argc >= 1) { if (strcmp(*argv, "-inform") == 0) { if (--argc < 1) goto bad; informat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; derfile= *(++argv); } else if (strcmp(*argv, "-i") == 0) { indent = 1; } else if (strcmp(*argv, "-noout") == 0) noout = 1; else if (strcmp(*argv, "-oid") == 0) { if (--argc < 1) goto bad; oidfile= *(++argv); } else if (strcmp(*argv, "-offset") == 0) { if (--argc < 1) goto bad; offset = atoi(*(++argv)); } else if (strcmp(*argv, "-length") == 0) { if (--argc < 1) goto bad; length = atoi(*(++argv)); if (length == 0) goto bad; } else if (strcmp(*argv, "-dump") == 0) { dump = -1; } else if (strcmp(*argv, "-dlimit") == 0) { if (--argc < 1) goto bad; dump = atoi(*(++argv)); if (dump <= 0) goto bad; } else if (strcmp(*argv, "-strparse") == 0) { if (--argc < 1) goto bad; sk_OPENSSL_STRING_push(osk, *(++argv)); } else if (strcmp(*argv, "-genstr") == 0) { if (--argc < 1) goto bad; genstr= *(++argv); } else if (strcmp(*argv, "-genconf") == 0) { if (--argc < 1) goto bad; genconf= *(++argv); } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err, "%s [options] <infile\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -out arg output file (output format is always DER\n"); BIO_printf(bio_err, " -noout arg don't produce any output\n"); BIO_printf(bio_err, " -offset arg offset into file\n"); BIO_printf(bio_err, " -length arg length of section in file\n"); BIO_printf(bio_err, " -i indent entries\n"); BIO_printf(bio_err, " -dump dump unknown data in hex form\n"); BIO_printf(bio_err, " -dlimit arg dump the first arg bytes of unknown data in hex form\n"); BIO_printf(bio_err, " -oid file file of extra oid definitions\n"); BIO_printf(bio_err, " -strparse offset\n"); BIO_printf(bio_err, " a series of these can be used to 'dig' into multiple\n"); BIO_printf(bio_err, " ASN1 blob wrappings\n"); BIO_printf(bio_err, " -genstr str string to generate ASN1 structure from\n"); BIO_printf(bio_err, " -genconf file file to generate ASN1 structure from\n"); goto end; } ERR_load_crypto_strings(); in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } BIO_set_fp(out, stdout, BIO_NOCLOSE|BIO_FP_TEXT); if (oidfile != NULL) { if (BIO_read_filename(in, oidfile) <= 0) { BIO_printf(bio_err, "problems opening %s\n", oidfile); ERR_print_errors(bio_err); goto end; } OBJ_create_objects(in); } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (derfile) { if (!(derout = BIO_new_file(derfile, "wb"))) { BIO_printf(bio_err, "problems opening %s\n", derfile); ERR_print_errors(bio_err); goto end; } } if ((buf = BUF_MEM_new()) == NULL) goto end; if (!BUF_MEM_grow(buf, BUFSIZ * 8)) goto end; /* Pre-allocate :-) */ if (genstr || genconf) { num = do_generate(bio_err, genstr, genconf, buf); if (num < 0) { ERR_print_errors(bio_err); goto end; } } else { if (informat == FORMAT_PEM) { BIO *tmp; if ((b64 = BIO_new(BIO_f_base64())) == NULL) goto end; BIO_push(b64, in); tmp = in; in = b64; b64 = tmp; } num = 0; for (;;) { if (!BUF_MEM_grow(buf, (int)num + BUFSIZ)) goto end; i = BIO_read(in, &(buf->data[num]), BUFSIZ); if (i <= 0) break; num += i; } } str = buf->data; /* If any structs to parse go through in sequence */ if (sk_OPENSSL_STRING_num(osk)) { tmpbuf = (unsigned char *)str; tmplen = num; for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) { ASN1_TYPE *atmp; int typ; j = atoi(sk_OPENSSL_STRING_value(osk, i)); if (j == 0) { BIO_printf(bio_err, "'%s' is an invalid number\n", sk_OPENSSL_STRING_value(osk, i)); continue; } tmpbuf += j; tmplen -= j; atmp = at; ctmpbuf = tmpbuf; at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen); ASN1_TYPE_free(atmp); if (!at) { BIO_printf(bio_err, "Error parsing structure\n"); ERR_print_errors(bio_err); goto end; } typ = ASN1_TYPE_get(at); if ((typ == V_ASN1_OBJECT) || (typ == V_ASN1_NULL)) { BIO_printf(bio_err, "Can't parse %s type\n", typ == V_ASN1_NULL ? "NULL" : "OBJECT"); ERR_print_errors(bio_err); goto end; } /* hmm... this is a little evil but it works */ tmpbuf = at->value.asn1_string->data; tmplen = at->value.asn1_string->length; } str = (char *)tmpbuf; num = tmplen; } if (offset >= num) { BIO_printf(bio_err, "Error: offset too large\n"); goto end; } num -= offset; if ((length == 0) || ((long)length > num)) length = (unsigned int)num; if (derout) { if (BIO_write(derout, str + offset, length) != (int)length) { BIO_printf(bio_err, "Error writing output\n"); ERR_print_errors(bio_err); goto end; } } if (!noout && !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length, indent, dump)) { ERR_print_errors(bio_err); goto end; } ret = 0; end: BIO_free(derout); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (b64 != NULL) BIO_free(b64); if (ret != 0) ERR_print_errors(bio_err); if (buf != NULL) BUF_MEM_free(buf); if (at != NULL) ASN1_TYPE_free(at); if (osk != NULL) sk_OPENSSL_STRING_free(osk); OBJ_cleanup(); apps_shutdown(); OPENSSL_EXIT(ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *signerfile = NULL, *recipfile = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; char *certsoutfile = NULL; const EVP_CIPHER *cipher = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; int badarg = 0; int flags = CMS_DETACHED, noout = 0, print = 0; int verify_retcode = 0; int rr_print = 0, rr_allorfirst = -1; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; CMS_ReceiptRequest *rr = NULL; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; const EVP_MD *sign_md = NULL; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif unsigned char *secret_key = NULL, *secret_keyid = NULL; unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; size_t secret_keylen = 0, secret_keyidlen = 0; ASN1_OBJECT *econtent_type = NULL; X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-sign_receipt")) operation = SMIME_SIGN_RECEIPT; else if (!strcmp (*args, "-resign")) operation = SMIME_RESIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-verify_retcode")) verify_retcode = 1; else if (!strcmp(*args,"-verify_receipt")) { operation = SMIME_VERIFY_RECEIPT; if (!args[1]) goto argerr; args++; rctfile = *args; } else if (!strcmp (*args, "-cmsout")) operation = SMIME_CMSOUT; else if (!strcmp (*args, "-data_out")) operation = SMIME_DATAOUT; else if (!strcmp (*args, "-data_create")) operation = SMIME_DATA_CREATE; else if (!strcmp (*args, "-digest_verify")) operation = SMIME_DIGEST_VERIFY; else if (!strcmp (*args, "-digest_create")) operation = SMIME_DIGEST_CREATE; else if (!strcmp (*args, "-compress")) operation = SMIME_COMPRESS; else if (!strcmp (*args, "-uncompress")) operation = SMIME_UNCOMPRESS; else if (!strcmp (*args, "-EncryptedData_decrypt")) operation = SMIME_ENCRYPTED_DECRYPT; else if (!strcmp (*args, "-EncryptedData_encrypt")) operation = SMIME_ENCRYPTED_ENCRYPT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-text")) flags |= CMS_TEXT; else if (!strcmp (*args, "-nointern")) flags |= CMS_NOINTERN; else if (!strcmp (*args, "-noverify") || !strcmp (*args, "-no_signer_cert_verify")) flags |= CMS_NO_SIGNER_CERT_VERIFY; else if (!strcmp (*args, "-nocerts")) flags |= CMS_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= CMS_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~CMS_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= CMS_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= CMS_BINARY; else if (!strcmp (*args, "-keyid")) flags |= CMS_USE_KEYID; else if (!strcmp (*args, "-nosigs")) flags |= CMS_NOSIGS; else if (!strcmp (*args, "-no_content_verify")) flags |= CMS_NO_CONTENT_VERIFY; else if (!strcmp (*args, "-no_attr_verify")) flags |= CMS_NO_ATTR_VERIFY; else if (!strcmp (*args, "-stream")) flags |= CMS_STREAM; else if (!strcmp (*args, "-indef")) flags |= CMS_STREAM; else if (!strcmp (*args, "-noindef")) flags &= ~CMS_STREAM; else if (!strcmp (*args, "-nooldmime")) flags |= CMS_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= CMS_CRLFEOL; else if (!strcmp (*args, "-noout")) noout = 1; else if (!strcmp (*args, "-receipt_request_print")) rr_print = 1; else if (!strcmp (*args, "-receipt_request_all")) rr_allorfirst = 0; else if (!strcmp (*args, "-receipt_request_first")) rr_allorfirst = 1; else if (!strcmp(*args,"-receipt_request_from")) { if (!args[1]) goto argerr; args++; if (!rr_from) rr_from = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_from, *args); } else if (!strcmp(*args,"-receipt_request_to")) { if (!args[1]) goto argerr; args++; if (!rr_to) rr_to = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_to, *args); } else if (!strcmp (*args, "-print")) { noout = 1; print = 1; } else if (!strcmp(*args,"-secretkey")) { long ltmp; if (!args[1]) goto argerr; args++; secret_key = string_to_hex(*args, <mp); if (!secret_key) { BIO_printf(bio_err, "Invalid key %s\n", *args); goto argerr; } secret_keylen = (size_t)ltmp; } else if (!strcmp(*args,"-secretkeyid")) { long ltmp; if (!args[1]) goto argerr; args++; secret_keyid = string_to_hex(*args, <mp); if (!secret_keyid) { BIO_printf(bio_err, "Invalid id %s\n", *args); goto argerr; } secret_keyidlen = (size_t)ltmp; } else if (!strcmp(*args,"-pwri_password")) { if (!args[1]) goto argerr; args++; pwri_pass = (unsigned char *)*args; } else if (!strcmp(*args,"-econtent_type")) { if (!args[1]) goto argerr; args++; econtent_type = OBJ_txt2obj(*args, 0); if (!econtent_type) { BIO_printf(bio_err, "Invalid OID %s\n", *args); goto argerr; } } else if (!strcmp(*args,"-rand")) { if (!args[1]) goto argerr; args++; inrand = *args; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (!args[1]) goto argerr; engine = *++args; } #endif else if (!strcmp(*args,"-passin")) { if (!args[1]) goto argerr; passargin = *++args; } else if (!strcmp (*args, "-to")) { if (!args[1]) goto argerr; to = *++args; } else if (!strcmp (*args, "-from")) { if (!args[1]) goto argerr; from = *++args; } else if (!strcmp (*args, "-subject")) { if (!args[1]) goto argerr; subject = *++args; } else if (!strcmp (*args, "-signer")) { if (!args[1]) goto argerr; /* If previous -signer argument add signer to list */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!keyfile) keyfile = signerfile; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = *++args; } else if (!strcmp (*args, "-recip")) { if (!args[1]) goto argerr; recipfile = *++args; } else if (!strcmp (*args, "-certsout")) { if (!args[1]) goto argerr; certsoutfile = *++args; } else if (!strcmp (*args, "-md")) { if (!args[1]) goto argerr; sign_md = EVP_get_digestbyname(*++args); if (sign_md == NULL) { BIO_printf(bio_err, "Unknown digest %s\n", *args); goto argerr; } } else if (!strcmp (*args, "-inkey")) { if (!args[1]) goto argerr; /* If previous -inkey arument add signer to list */ if (keyfile) { if (!signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = *++args; } else if (!strcmp (*args, "-keyform")) { if (!args[1]) goto argerr; keyform = str2fmt(*++args); } else if (!strcmp (*args, "-rctform")) { if (!args[1]) goto argerr; rctformat = str2fmt(*++args); } else if (!strcmp (*args, "-certfile")) { if (!args[1]) goto argerr; certfile = *++args; } else if (!strcmp (*args, "-CAfile")) { if (!args[1]) goto argerr; CAfile = *++args; } else if (!strcmp (*args, "-CApath")) { if (!args[1]) goto argerr; CApath = *++args; } else if (!strcmp (*args, "-in")) { if (!args[1]) goto argerr; infile = *++args; } else if (!strcmp (*args, "-inform")) { if (!args[1]) goto argerr; informat = str2fmt(*++args); } else if (!strcmp (*args, "-outform")) { if (!args[1]) goto argerr; outformat = str2fmt(*++args); } else if (!strcmp (*args, "-out")) { if (!args[1]) goto argerr; outfile = *++args; } else if (!strcmp (*args, "-content")) { if (!args[1]) goto argerr; contfile = *++args; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) badarg = 1; args++; } if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto argerr; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } /* Check to see if any final signer needs to be appended */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile && !secret_key && !pwri_pass) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args && !secret_key && !pwri_pass) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { argerr: BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-cmsout output CMS structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-certsout file certificate output file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-keyid use subject key identifier\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (!(operation & SMIME_SIGNERS)) flags &= ~CMS_DETACHED; if (operation & SMIME_OP) { if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & CMS_BINARY) outmode = "wb"; } if (operation & SMIME_IP) { if (informat == FORMAT_ASN1) inmode = "rb"; } else { if (flags & CMS_BINARY) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } if (secret_key && !secret_keyid) { BIO_printf(bio_err, "No secret key id\n"); goto end; } if (*args) encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) goto end; sk_X509_push(encerts, cert); cert = NULL; args++; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_SIGN_RECEIPT) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL, e, "receipt signer certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) cms = SMIME_read_CMS(in, &indata); else if (informat == FORMAT_PEM) cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) cms = d2i_CMS_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for CMS file\n"); goto end; } if (!cms) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } if (certsoutfile) { STACK_OF(X509) *allcerts; allcerts = CMS_get1_certs(cms); if (!save_certs(certsoutfile, allcerts)) { BIO_printf(bio_err, "Error writing certs to %s\n", certsoutfile); ret = 5; goto end; } sk_X509_pop_free(allcerts, X509_free); } } if (rctfile) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; if (!(rctin = BIO_new_file(rctfile, rctmode))) { BIO_printf (bio_err, "Can't open receipt file %s\n", rctfile); goto end; } if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) rcms = d2i_CMS_bio(rctin, NULL); else { BIO_printf(bio_err, "Bad input format for receipt\n"); goto end; } if (!rcms) { BIO_printf(bio_err, "Error reading receipt\n"); goto end; } } if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_DATA_CREATE) { cms = CMS_data_create(in, flags); } else if (operation == SMIME_DIGEST_CREATE) { cms = CMS_digest_create(in, sign_md, flags); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { flags |= CMS_PARTIAL; cms = CMS_encrypt(encerts, in, cipher, flags); if (!cms) goto end; if (secret_key) { if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, secret_keylen, secret_keyid, secret_keyidlen, NULL, NULL, NULL)) goto end; /* NULL these because call absorbs them */ secret_key = NULL; secret_keyid = NULL; } if (pwri_pass) { pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass); if (!pwri_tmp) goto end; if (!CMS_add0_recipient_password(cms, -1, NID_undef, NID_undef, pwri_tmp, -1, NULL)) goto end; pwri_tmp = NULL; } if (!(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, secret_keylen, flags); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; STACK_OF(CMS_SignerInfo) *sis; CMS_SignerInfo *si; sis = CMS_get0_SignerInfos(cms); if (!sis) goto end; si = sk_CMS_SignerInfo_value(sis, 0); srcms = CMS_sign_receipt(si, signer, key, other, flags); if (!srcms) goto end; CMS_ContentInfo_free(cms); cms = srcms; } else if (operation & SMIME_SIGNERS) { int i; /* If detached data content we enable streaming if * S/MIME output format. */ if (operation == SMIME_SIGN) { if (flags & CMS_DETACHED) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; cms = CMS_sign(NULL, NULL, other, in, flags); if (!cms) goto end; if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if (rr_to) { rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); if (!rr) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); goto end; } } } else flags |= CMS_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; si = CMS_add1_signer(cms, signer, key, sign_md, flags); if (!si) goto end; if (rr && !CMS_add1_ReceiptRequest(si, rr)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } if (!cms) { BIO_printf(bio_err, "Error creating CMS structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (secret_key) { if (!CMS_decrypt_set1_key(cms, secret_key, secret_keylen, secret_keyid, secret_keyidlen)) { BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); goto end; } } if (key) { if (!CMS_decrypt_set1_pkey(cms, key, recip)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } } if (pwri_pass) { if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { BIO_puts(bio_err, "Error decrypting CMS using password\n"); goto end; } } if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } } else if (operation == SMIME_DATAOUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { if (!CMS_uncompress(cms, indata, out, flags)) goto end; } else if (operation == SMIME_DIGEST_VERIFY) { if (CMS_digest_verify(cms, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else if (operation == SMIME_ENCRYPTED_DECRYPT) { if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, indata, out, flags)) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile) { STACK_OF(X509) *signers; signers = CMS_get0_signers(cms); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } if (rr_print) receipt_request_print(bio_err, cms); } else if (operation == SMIME_VERIFY_RECEIPT) { if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else { if (noout) { if (print) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) ret = i2d_CMS_bio_stream(out,cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); goto end; } if (ret <= 0) { ret = 6; goto end; } } ret = 0; end: if (ret) ERR_print_errors(bio_err); if (need_rand) app_RAND_write_file(NULL, bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); if (sksigners) sk_OPENSSL_STRING_free(sksigners); if (skkeys) sk_OPENSSL_STRING_free(skkeys); if (secret_key) OPENSSL_free(secret_key); if (secret_keyid) OPENSSL_free(secret_keyid); if (pwri_tmp) OPENSSL_free(pwri_tmp); if (econtent_type) ASN1_OBJECT_free(econtent_type); if (rr) CMS_ReceiptRequest_free(rr); if (rr_to) sk_OPENSSL_STRING_free(rr_to); if (rr_from) sk_OPENSSL_STRING_free(rr_from); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); BIO_free(rctin); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }