// Minimal TLS server. This is largely based on the example at // https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core // internals in src/core/lib/tsi/ssl_transport_security.c. static void server_thread(void *arg) { const server_args *args = (server_args *)arg; SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); const SSL_METHOD *method = TLSv1_2_server_method(); SSL_CTX *ctx = SSL_CTX_new(method); if (!ctx) { perror("Unable to create SSL context"); ERR_print_errors_fp(stderr); abort(); } // Load key pair. if (SSL_CTX_use_certificate_file(ctx, SSL_CERT_PATH, SSL_FILETYPE_PEM) < 0) { ERR_print_errors_fp(stderr); abort(); } if (SSL_CTX_use_PrivateKey_file(ctx, SSL_KEY_PATH, SSL_FILETYPE_PEM) < 0) { ERR_print_errors_fp(stderr); abort(); } // Set the cipher list to match the one expressed in // src/core/lib/tsi/ssl_transport_security.c. const char *cipher_list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" "SHA384:ECDHE-RSA-AES256-GCM-SHA384"; if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) { ERR_print_errors_fp(stderr); gpr_log(GPR_ERROR, "Couldn't set server cipher list."); abort(); } // Register the ALPN selection callback. SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, args->alpn_preferred); // bind/listen/accept at TCP layer. const int sock = args->socket; gpr_log(GPR_INFO, "Server listening"); struct sockaddr_in addr; socklen_t len = sizeof(addr); const int client = accept(sock, (struct sockaddr *)&addr, &len); if (client < 0) { perror("Unable to accept"); abort(); } // Establish a SSL* and accept at SSL layer. SSL *ssl = SSL_new(ctx); GPR_ASSERT(ssl); SSL_set_fd(ssl, client); if (SSL_accept(ssl) <= 0) { ERR_print_errors_fp(stderr); gpr_log(GPR_ERROR, "Handshake failed."); } else { gpr_log(GPR_INFO, "Handshake successful."); } // Wait until the client drops its connection. char buf; while (SSL_read(ssl, &buf, sizeof(buf)) > 0) ; SSL_free(ssl); close(client); close(sock); SSL_CTX_free(ctx); EVP_cleanup(); }
rdpRsaKey* key_new(const char* keyfile) { FILE* fp; RSA* rsa; rdpRsaKey* key; key = (rdpRsaKey*) malloc(sizeof(rdpRsaKey)); ZeroMemory(key, sizeof(rdpRsaKey)); if (key == NULL) return NULL; fp = fopen(keyfile, "r"); if (fp == NULL) { fprintf(stderr, "unable to load RSA key from %s: %s.", keyfile, strerror(errno)); free(key) ; return NULL; } rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); if (rsa == NULL) { ERR_print_errors_fp(stdout); fclose(fp); free(key) ; return NULL; } fclose(fp); switch (RSA_check_key(rsa)) { case 0: RSA_free(rsa); fprintf(stderr, "invalid RSA key in %s", keyfile); free(key) ; return NULL; case 1: /* Valid key. */ break; default: ERR_print_errors_fp(stderr); RSA_free(rsa); free(key) ; return NULL; } if (BN_num_bytes(rsa->e) > 4) { RSA_free(rsa); fprintf(stderr, "RSA public exponent too large in %s", keyfile); free(key) ; return NULL; } key->ModulusLength = BN_num_bytes(rsa->n); key->Modulus = (BYTE*) malloc(key->ModulusLength); BN_bn2bin(rsa->n, key->Modulus); crypto_reverse(key->Modulus, key->ModulusLength); key->PrivateExponentLength = BN_num_bytes(rsa->d); key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength); BN_bn2bin(rsa->d, key->PrivateExponent); crypto_reverse(key->PrivateExponent, key->PrivateExponentLength); memset(key->exponent, 0, sizeof(key->exponent)); BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e)); crypto_reverse(key->exponent, sizeof(key->exponent)); RSA_free(rsa); return key; }
int main(int argc, char *argv[]) { FILE *fin, *fkey; u_int16_t siglen; u_int32_t magic; long nread, ndata; char *sigbuf, *inbuf; EVP_PKEY *pkey; EVP_MD_CTX ctx; int err, retval; if (argc != 3) usage(); ERR_load_crypto_strings(); /* open file and check for magic */ fin = fopen(argv[2], "r+"); if (fin == NULL) { fprintf(stderr, "unable to open file '%s'\n", argv[2]); exit(4); } fseek(fin, -(sizeof(magic)), SEEK_END); fread(&magic, sizeof(magic), 1, fin); if (magic != SIG_MAGIC) { fclose(fin); exit(2); } /* magic is good; get signature length */ fseek(fin, -(sizeof(magic) + sizeof(siglen)), SEEK_END); fread(&siglen, sizeof(siglen), 1, fin); /* read public key */ fkey = fopen(argv[1], "r"); if (fkey == NULL) { fprintf(stderr, "unable to open public key file '%s'\n", argv[1]); exit(4); } pkey = PEM_read_PUBKEY(fkey, NULL, NULL, NULL); fclose(fkey); if (pkey == NULL) { ERR_print_errors_fp(stderr); exit(4); } /* check if siglen is sane */ if ((siglen == 0) || (siglen > EVP_PKEY_size(pkey))) exit(3); /* got signature length; read signature */ sigbuf = malloc(siglen); if (sigbuf == NULL) exit(4); fseek(fin, -(sizeof(magic) + sizeof(siglen) + siglen), SEEK_END); if (fread(sigbuf, 1, siglen, fin) != siglen) exit(4); /* signature read; truncate file to remove sig */ fseek(fin, 0, SEEK_END); ndata = ftell(fin) - (sizeof(magic) + sizeof(siglen) + siglen); ftruncate(fileno(fin), ndata); /* verify the signature now */ EVP_VerifyInit(&ctx, EVP_sha1()); /* allocate data buffer */ inbuf = malloc(SIG_INBUFLEN); if (inbuf == NULL) exit(4); rewind(fin); while (!feof(fin)) { nread = fread(inbuf, 1, SIG_INBUFLEN, fin); if (nread != SIG_INBUFLEN) { if (ferror(fin)) { fprintf(stderr, "read error in file '%s'\n", argv[2]); exit(4); } } EVP_VerifyUpdate(&ctx, inbuf, nread); } err = EVP_VerifyFinal(&ctx, sigbuf, siglen, pkey); EVP_PKEY_free(pkey); if (err == 1) retval = 0; /* correct signature */ else if (err == 0) retval = 1; /* invalid signature */ else retval = 3; /* error */ free(inbuf); free(sigbuf); fclose(fin); return retval; }
SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile): pCtx (NULL), PrivateKey (NULL), Certificate (NULL) { /* TODO: the usage of the specified private-key and cert-chain filenames only applies to * client-side connections at this point. Server connections currently use the default materials. * That needs to be fixed asap. * Also, in this implementation, server-side connections use statically defined X-509 defaults. * One thing I'm really not clear on is whether or not you have to explicitly free X509 and EVP_PKEY * objects when we call our destructor, or whether just calling SSL_CTX_free is enough. */ if (!bLibraryInitialized) { bLibraryInitialized = true; SSL_library_init(); OpenSSL_add_ssl_algorithms(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); ERR_load_crypto_strings(); InitializeDefaultCredentials(); } bIsServer = is_server; pCtx = SSL_CTX_new (is_server ? SSLv23_server_method() : SSLv23_client_method()); if (!pCtx) throw std::runtime_error ("no SSL context"); SSL_CTX_set_options (pCtx, SSL_OP_ALL); //SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3)); if (is_server) { // The SSL_CTX calls here do NOT allocate memory. int e; if (privkeyfile.length() > 0) e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM); else e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey); if (e <= 0) ERR_print_errors_fp(stderr); assert (e > 0); if (certchainfile.length() > 0) e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str()); else e = SSL_CTX_use_certificate (pCtx, DefaultCertificate); if (e <= 0) ERR_print_errors_fp(stderr); assert (e > 0); } SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH"); if (is_server) { SSL_CTX_sess_set_cache_size (pCtx, 128); SSL_CTX_set_session_id_context (pCtx, (unsigned char*)"eventmachine", 12); } else { int e; if (privkeyfile.length() > 0) { e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM); if (e <= 0) ERR_print_errors_fp(stderr); assert (e > 0); } if (certchainfile.length() > 0) { e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str()); if (e <= 0) ERR_print_errors_fp(stderr); assert (e > 0); } } }
int main(int argc, char *argv[]) { BN_CTX *ctx; BIO *out; char *outfile=NULL; results = 0; RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-results") == 0) results=1; else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) break; outfile= *(++argv); } argc--; argv++; } ctx=BN_CTX_new(); if (ctx == NULL) EXIT(1); out=BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); } else { if (!BIO_write_filename(out,outfile)) { perror(outfile); EXIT(1); } } if (!results) BIO_puts(out,"obase=16\nibase=16\n"); message(out,"BN_add"); if (!test_add(out)) goto err; BIO_flush(out); message(out,"BN_sub"); if (!test_sub(out)) goto err; BIO_flush(out); message(out,"BN_lshift1"); if (!test_lshift1(out)) goto err; BIO_flush(out); message(out,"BN_lshift (fixed)"); if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL))) goto err; BIO_flush(out); message(out,"BN_lshift"); if (!test_lshift(out,ctx,NULL)) goto err; BIO_flush(out); message(out,"BN_rshift1"); if (!test_rshift1(out)) goto err; BIO_flush(out); message(out,"BN_rshift"); if (!test_rshift(out,ctx)) goto err; BIO_flush(out); message(out,"BN_sqr"); if (!test_sqr(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mul"); if (!test_mul(out)) goto err; BIO_flush(out); message(out,"BN_div"); if (!test_div(out,ctx)) goto err; BIO_flush(out); message(out,"BN_div_recp"); if (!test_div_recp(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mod"); if (!test_mod(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mod_mul"); if (!test_mod_mul(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mont"); if (!test_mont(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mod_exp"); if (!test_mod_exp(out,ctx)) goto err; BIO_flush(out); message(out,"BN_exp"); if (!test_exp(out,ctx)) goto err; BIO_flush(out); message(out,"BN_kronecker"); if (!test_kron(out,ctx)) goto err; BIO_flush(out); message(out,"BN_mod_sqrt"); if (!test_sqrt(out,ctx)) goto err; BIO_flush(out); BN_CTX_free(ctx); BIO_free(out); /**/ EXIT(0); err: BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices * the failure, see test_bn in test/Makefile.ssl*/ BIO_flush(out); ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); EXIT(1); return(1); }
static void digest(struct executable *x) { EVP_MD_CTX *mdctx; const EVP_MD *md; size_t sum_of_bytes_hashed; int i, ok; /* * Windows Authenticode Portable Executable Signature Format * spec version 1.0 specifies MD5 and SHA1. However, pesign * and sbsign both use SHA256, so do the same. */ md = EVP_get_digestbyname(DIGEST); if (md == NULL) { ERR_print_errors_fp(stderr); errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST); } mdctx = EVP_MD_CTX_create(); if (mdctx == NULL) { ERR_print_errors_fp(stderr); errx(1, "EVP_MD_CTX_create(3) failed"); } ok = EVP_DigestInit_ex(mdctx, md, NULL); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "EVP_DigestInit_ex(3) failed"); } /* * According to the Authenticode spec, we need to compute * the digest in a rather... specific manner; see "Calculating * the PE Image Hash" part of the spec for details. * * First, everything from 0 to before the PE checksum. */ digest_range(x, mdctx, 0, x->x_checksum_off); /* * Second, from after the PE checksum to before the Certificate * entry in Data Directory. */ digest_range(x, mdctx, x->x_checksum_off + x->x_checksum_len, x->x_certificate_entry_off - (x->x_checksum_off + x->x_checksum_len)); /* * Then, from after the Certificate entry to the end of headers. */ digest_range(x, mdctx, x->x_certificate_entry_off + x->x_certificate_entry_len, x->x_headers_len - (x->x_certificate_entry_off + x->x_certificate_entry_len)); /* * Then, each section in turn, as specified in the PE Section Table. * * XXX: Sorting. */ sum_of_bytes_hashed = x->x_headers_len; for (i = 0; i < x->x_nsections; i++) { digest_range(x, mdctx, x->x_section_off[i], x->x_section_len[i]); sum_of_bytes_hashed += x->x_section_len[i]; } /* * I believe this can happen with overlapping sections. */ if (sum_of_bytes_hashed > x->x_len) errx(1, "number of bytes hashed is larger than file size"); /* * I can't really explain this one; just do what the spec says. */ if (sum_of_bytes_hashed < x->x_len) { digest_range(x, mdctx, sum_of_bytes_hashed, x->x_len - (signature_size(x) + sum_of_bytes_hashed)); } ok = EVP_DigestFinal_ex(mdctx, x->x_digest, &x->x_digest_len); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "EVP_DigestFinal_ex(3) failed"); } EVP_MD_CTX_destroy(mdctx); }
/** * \brief Funtion that listens for new connetions * * Runs in a thread and adds new connections to plugin_conf->master set * * \param[in, out] config Plugin configuration structure * \return NULL always */ void *input_listen(void *config) { struct plugin_conf *conf = (struct plugin_conf *) config; int new_sock; /* use IPv6 sockaddr structure to store address information (IPv4 fits easily) */ struct sockaddr_in6 *address = NULL; socklen_t addr_length; char src_addr[INET6_ADDRSTRLEN]; struct input_info_list *input_info; #ifdef TLS_SUPPORT int ret; int i; SSL *ssl = NULL; /* structure for TLS connection */ X509 *peer_cert = NULL; /* peer's certificate */ struct cleanup maid; /* auxiliary struct for TLS error handling */ #endif /* loop ends when thread is cancelled by pthread_cancel() function */ while (1) { /* allocate space for the address */ addr_length = sizeof(struct sockaddr_in6); address = malloc(addr_length); if (!address) { MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__); break; } /* ensure that address will be freed when thread is canceled */ pthread_cleanup_push(input_listen_cleanup, (void *) address); if ((new_sock = accept(conf->socket, (struct sockaddr*) address, &addr_length)) == -1) { MSG_ERROR(msg_module, "Cannot accept new socket: %s", strerror(errno)); /* exit and call cleanup */ pthread_exit(0); } #ifdef TLS_SUPPORT /* preparation for TLS error handling */ maid.address = address; maid.ssl = NULL; maid.peer_cert = NULL; if (conf->tls) { /* create a new SSL structure for the connection */ ssl = SSL_new(conf->ctx); if (!ssl) { MSG_ERROR(msg_module, "Unable to create SSL structure"); ERR_print_errors_fp(stderr); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } maid.ssl = ssl; /* connect the SSL object with the socket */ ret = SSL_set_fd(ssl, new_sock); if (ret != 1) { MSG_ERROR(msg_module, "Unable to connect the SSL object with the socket"); ERR_print_errors_fp(stderr); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } /* TLS handshake */ ret = SSL_accept(ssl); if (ret != 1) { /* handshake wasn't successful */ MSG_ERROR(msg_module, "TLS handshake was not successful"); ERR_print_errors_fp(stderr); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } /* obtain peer's certificate */ peer_cert = SSL_get_peer_certificate(ssl); if (!peer_cert) { MSG_ERROR(msg_module, "No certificate was presented by the peer"); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } maid.peer_cert = peer_cert; /* verify peer's certificate */ if (SSL_get_verify_result(ssl) != X509_V_OK) { MSG_ERROR(msg_module, "Client sent bad certificate; verification failed"); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } /* put new SSL structure into the conf->ssl_list */ for (i = 0; i < conf->ssl_list_size; i++) { if (conf->ssl_list[i] == NULL) { conf->ssl_list[i] = ssl; } } if (conf->ssl_list[i] != ssl) { /* limit reached. no space for new SSL structure */ MSG_WARNING(msg_module, "Reached limit on the number of TLS connections; tearing down this connection..."); /* cleanup */ input_listen_tls_cleanup(conf, &maid); continue; } } #endif pthread_mutex_lock(&mutex); FD_SET(new_sock, &conf->master); if (conf->fd_max < new_sock) { conf->fd_max = new_sock; } /* copy socket address to config structure */ if (!add_sock_address(conf, address, new_sock)) { MSG_ERROR(msg_module, "Cannot store another socket address"); break; } /* print info */ if (conf->info.l3_proto == 4) { inet_ntop(AF_INET, (void *)&((struct sockaddr_in*) address)->sin_addr, src_addr, INET6_ADDRSTRLEN); } else { inet_ntop(AF_INET6, &address->sin6_addr, src_addr, INET6_ADDRSTRLEN); } MSG_INFO(msg_module, "Exporter connected from address %s", src_addr); pthread_mutex_unlock(&mutex); /* create new input_info for this connection */ input_info = calloc(1, sizeof(struct input_info_list)); if (input_info == NULL) { MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__); break; } memcpy(&input_info->info, &conf->info, sizeof(struct input_info_network)); /* set status to new connection */ input_info->info.status = SOURCE_STATUS_NEW; /* copy address and port */ if (address->sin6_family == AF_INET) { /* copy src IPv4 address */ input_info->info.src_addr.ipv4.s_addr = ((struct sockaddr_in*) address)->sin_addr.s_addr; /* copy port */ input_info->info.src_port = ntohs(((struct sockaddr_in*) address)->sin_port); } else { /* copy src IPv6 address */ int i; for (i=0; i<4; i++) { input_info->info.src_addr.ipv6.s6_addr32[i] = address->sin6_addr.s6_addr32[i]; } /* copy port */ input_info->info.src_port = ntohs(address->sin6_port); } #ifdef TLS_SUPPORT /* fill in certificates */ input_info->collector_cert = conf->server_cert_file; input_info->exporter_cert = peer_cert; #endif /* add to list */ input_info->next = conf->info_list; conf->info_list = input_info; /* unset the address so that we do not free it incidentally */ address = NULL; pthread_cleanup_pop(0); } return NULL; }
int fips_check_rsa(RSA *rsa) { int n, ret = 0; unsigned char tctext[256], *ctext = tctext; unsigned char tptext[256], *ptext = tptext; /* The longest we can have with PKCS#1 v1.5 padding and a 512 bit key, * namely 512/8-11-1 = 52 bytes */ static const unsigned char original_ptext[] = "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef" "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef" "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef" "\x01\x23\x45\x67"; if (RSA_size(rsa) > sizeof(tctext)) { ctext = OPENSSL_malloc(RSA_size(rsa)); ptext = OPENSSL_malloc(RSA_size(rsa)); if (!ctext || !ptext) { ERR_print_errors_fp(OPENSSL_stderr()); exit(1); } } /* this will fail for keys shorter than 512 bits */ n=RSA_private_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,rsa, RSA_PKCS1_PADDING); if(n < 0) { ERR_print_errors_fp(OPENSSL_stderr()); exit(1); } if(!memcmp(ctext,original_ptext,n)) { FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); goto error; } n=RSA_public_decrypt(n,ctext,ptext,rsa,RSA_PKCS1_PADDING); if(n < 0) { ERR_print_errors_fp(OPENSSL_stderr()); exit(1); } if(n != sizeof(original_ptext)-1 || memcmp(ptext,original_ptext,n)) { FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); goto error; } ret = 1; error: if (RSA_size(rsa) > sizeof(tctext)) { OPENSSL_free(ctext); OPENSSL_free(ptext); } return ret; }
krb5_data * krb5_cproxy_process(char *servername, char *port, krb5_data *request) { /* SSL init */ SSL_library_init(); /* always returns 1 */ SSL_load_error_strings(); OpenSSL_add_all_algorithms(); const SSL_METHOD *method = SSLv23_client_method(); /* includes TLSv1 */ if (!method) { ERR_print_errors_fp(stderr); EVP_cleanup(); return NULL; } SSL_CTX *gamma = SSL_CTX_new(method); if (!gamma) { ERR_print_errors_fp(stderr); EVP_cleanup(); return NULL; } SSL_CTX_set_verify(gamma, SSL_VERIFY_PEER, NULL); if (!SSL_CTX_set_default_verify_paths(gamma)) { ERR_print_errors_fp(stderr); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } SSL *ssl = SSL_new(gamma); if (!ssl) { ERR_print_errors_fp(stderr); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } /* Encoding */ char *req; gsize out_len; char *fmt = "POST / HTTP/1.0\r\n" "Host: %s\r\n" /* MSFT gets upset without this */ "Content-type: application/kerberos\r\n" "Content-length: %d\r\n" "\r\n%s"; char *g_buf = g_base64_encode((guchar *) request->data, request->length); size_t reqlen = asprintf(&req, fmt, servername, strlen(g_buf), g_buf); g_free(g_buf); /* connect to other proxy */ struct addrinfo khints, *kserverdata; memset(&khints, 0, sizeof(khints)); khints.ai_family = AF_UNSPEC; khints.ai_socktype = SOCK_STREAM; /* TCP for HTTP */ int gai_ret = getaddrinfo(servername, port, &khints, &kserverdata); if (gai_ret) { fprintf(stderr, "%s\n", gai_strerror(gai_ret)); SSL_CTX_free(gamma); EVP_cleanup(); free(req); return NULL; } int fd_prox = -1; for (struct addrinfo *cur = kserverdata; cur != NULL && fd_prox == -1; cur = cur->ai_next) { fd_prox = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); if (fd_prox == -1) { fprintf(stderr, "failed to socket\n"); } else if (connect(fd_prox, cur->ai_addr, cur->ai_addrlen) == -1) { close(fd_prox); fd_prox = -1; fprintf(stderr, "failed to connect\n"); } } freeaddrinfo(kserverdata); if (fd_prox == -1) { fprintf(stderr, "unable to connect to any sockets\n"); SSL_CTX_free(gamma); EVP_cleanup(); free(req); return NULL; } /* SSL the socket */ if (!SSL_set_fd(ssl, fd_prox)) { ERR_print_errors_fp(stderr); close(fd_prox); free(req); SSL_free(ssl); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } if (SSL_connect(ssl) != 1) { ERR_print_errors_fp(stderr); /* maybe? */ close(fd_prox); free(req); SSL_free(ssl); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } /* send, get the KDCPROXY's reply */ if (!SSL_write(ssl, req, reqlen)) { ERR_print_errors_fp(stderr); /* maybe */ close(fd_prox); SSL_free(ssl); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } free(req); char buf[BUF_SIZE]; char *bufptr = buf; int length; do { length = SSL_read(ssl, bufptr, BUF_SIZE - 1 + bufptr - buf); printf("length: %d\n", length); if (length < 0) { ERR_print_errors_fp(stderr); /* maybe? */ close(fd_prox); SSL_free(ssl); SSL_CTX_free(gamma); EVP_cleanup(); return NULL; } bufptr += length; } while (length > 0); *bufptr = '\0'; close(fd_prox); SSL_free(ssl); SSL_CTX_free(gamma); EVP_cleanup(); /* forward the reply to the requester */ char *rep = strstr(buf, "\r\n\r\n"); if (rep == NULL) { fprintf(stderr, "didn't get back krb response from proxy\n"); return NULL; } rep += 4; guchar *res = g_base64_decode(rep, &out_len); krb5_data *response = malloc(sizeof(krb5_data)); response->length = out_len; response->data = malloc(sizeof(char)*(out_len + 1)); memcpy(response->data, res, out_len); (response->data)[out_len] = '\0'; g_free(res); return response; }
int main(int argc, char **argv) { //ENGINE *e = NULL; int c, host_port = 80, count = 1; char *host_name, *p, *dir_name = NULL; char http_string[16384]; struct http_reply reply; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; struct scep scep_t; FILE *fp = NULL; BIO *bp; STACK_OF(X509) *nextcara = NULL; X509 *cert=NULL; PKCS7 p7; int i; int required_option_space; #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; //printf("Starting sscep\n"); //fprintf(stdout, "%s: starting sscep on WIN32, sscep version %s\n", pname, VERSION); wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return; } #endif /* Initialize scep layer */ init_scep(); /* Set program name */ pname = argv[0]; /* Set timeout */ timeout = TIMEOUT; /* Check operation parameter */ if (!argv[1]) { usage(); } else if (!strncmp(argv[1], "getca", 5)) { operation_flag = SCEP_OPERATION_GETCA; } else if (!strncmp(argv[1], "enroll", 6)) { operation_flag = SCEP_OPERATION_ENROLL; } else if (!strncmp(argv[1], "getcert", 7)) { operation_flag = SCEP_OPERATION_GETCERT; } else if (!strncmp(argv[1], "getcrl", 6)) { operation_flag = SCEP_OPERATION_GETCRL; } else if (!strncmp(argv[1], "getnextca", 9)) { operation_flag = SCEP_OPERATION_GETNEXTCA; } else { fprintf(stderr, "%s: missing or illegal operation parameter\n", argv[0]); usage(); } /* Skip first parameter and parse the rest of the command */ optind++; while ((c = getopt(argc, argv, "c:C:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:HM:")) != -1) switch(c) { case 'c': c_flag = 1; c_char = optarg; break; case 'C': C_flag = 1; C_char = optarg; break; case 'd': d_flag = 1; break; case 'e': e_flag = 1; e_char = optarg; break; case 'E': E_flag = 1; E_char = optarg; break; case 'F': F_flag = 1; F_char = optarg; break; case 'f': f_flag = 1; f_char = optarg; break; case 'g': g_flag = 1; g_char = optarg; break; case 'h'://TODO change to eg. ID --inform=ID h_flag = 1; break; case 'H': H_flag = 1; break; case 'i': i_flag = 1; i_char = optarg; break; case 'k': k_flag = 1; k_char = optarg; break; case 'K': K_flag = 1; K_char = optarg; break; case 'l': l_flag = 1; l_char = optarg; break; case 'L': L_flag = 1; L_char = optarg; break; case 'm': m_flag = 1; m_char = optarg; break; case 'M': if(!M_flag) { /* if this is the first time the option appears, create a * new string. */ required_option_space = strlen(optarg) + 1; M_char = malloc(required_option_space); if(!M_char) error_memory(); strncpy(M_char, optarg, required_option_space); // set the flag, so we already have a string M_flag = 1; } else { /* we already have a string, just extend it. */ // old part + new part + &-sign + null byte required_option_space = strlen(M_char) + strlen(optarg) + 2; M_char = realloc(M_char, required_option_space); if(!M_char) error_memory(); strncat(M_char, "&", 1); strncat(M_char, optarg, strlen(optarg)); } break; case 'n': n_flag = 1; n_num = atoi(optarg); break; case 'O': O_flag = 1; O_char = optarg; break; case 'p': p_flag = 1; p_char = optarg; break; case 'r': r_flag = 1; r_char = optarg; break; case 'R': R_flag = 1; break; case 's': s_flag = 1; /*s_char = optarg;*/ s_char = handle_serial(optarg); break; case 'S': S_flag = 1; S_char = optarg; break; case 't': t_flag = 1; t_num = atoi(optarg); break; case 'T': T_flag = 1; T_num = atoi(optarg); break; case 'u': u_flag = 1; url_char = optarg; break; case 'v': v_flag = 1; break; case 'w': w_flag = 1; w_char = optarg; break; default: printf("argv: %s\n", argv[optind]); usage(); } argc -= optind; argv += optind; /* If we debug, include verbose messages also */ if (d_flag) v_flag = 1; if(f_char){ scep_conf_init(f_char); }else{ scep_conf = NULL; //moved init to here otherwise compile error on windows } /* Read in the configuration file: */ /*if (f_char) { #ifdef WIN32 if ((fopen_s(&fp, f_char, "r"))) #else if (!(fp = fopen(f_char, "r"))) #endif fprintf(stderr, "%s: cannot open %s\n", pname, f_char); else { init_config(fp); (void)fclose(fp); } }*/ if (v_flag) fprintf(stdout, "%s: starting sscep, version %s\n", pname, VERSION); /* * Create a new SCEP transaction and self-signed * certificate based on cert request */ if (v_flag) fprintf(stdout, "%s: new transaction\n", pname); new_transaction(&scep_t); /*enable Engine Support */ if (g_flag) { scep_t.e = scep_engine_init(scep_t.e); } /* * Check argument logic. */ if (!c_flag) { if (operation_flag == SCEP_OPERATION_GETCA) { fprintf(stderr, "%s: missing CA certificate filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing CA certificate (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate target filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing nextCA certificate target filename(-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (!C_flag) { if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate chain filename (-C)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_ENROLL) { if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!r_flag) { fprintf(stderr, "%s: missing request (-r)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } /* Set polling limits */ if (!n_flag) n_num = MAX_POLL_COUNT; if (!t_flag) t_num = POLL_TIME; if (!T_flag) T_num = MAX_POLL_TIME; } if (operation_flag == SCEP_OPERATION_GETCERT) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!s_flag) { fprintf(stderr, "%s: missing serial no (-s)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing cert file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_GETCRL) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing crl file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } #ifdef WIN32 else if (!(host_name = _strdup(url_char + 7))) #else else if (!(host_name = strdup(url_char + 7))) #endif error_memory(); p = host_name; c = 0; while (*p != '\0') { if (*p == '/' && !p_flag && !c) { *p = '\0'; if (*(p+1)) dir_name = p + 1; c = 1; } if (*p == ':') { *p = '\0'; if (*(p+1)) host_port = atoi(p+1); } p++; } if (!dir_name) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (host_port < 1 || host_port > 65550) { fprintf(stderr, "%s: illegal port number %d\n", pname, host_port); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) { fprintf(stdout, "%s: hostname: %s\n", pname, host_name); fprintf(stdout, "%s: directory: %s\n", pname, dir_name); fprintf(stdout, "%s: port: %d\n", pname, host_port); } /* Check algorithms */ if (!E_flag) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "blowfish", 8)) { enc_alg = (EVP_CIPHER *)EVP_bf_cbc(); } else if (!strncmp(E_char, "des", 3)) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "3des", 4)) { enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc(); } else if (!strncmp(E_char, "aes", 3)) { enc_alg = (EVP_CIPHER *)EVP_aes_256_cbc(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, E_char); exit (SCEP_PKISTATUS_ERROR); } if (!S_flag) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "md5", 3)) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "sha1", 4)) { sig_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, S_char); exit (SCEP_PKISTATUS_ERROR); } /* Fingerprint algorithm */ if (!F_flag) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "md5", 3)) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "sha1", 4)) { fp_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, F_char); exit (SCEP_PKISTATUS_ERROR); } /* * Switch to operation specific code */ switch(operation_flag) { case SCEP_OPERATION_GETCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting CA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "should define CA identifier (-i)\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if (v_flag){ printf("%s: valid response from server\n", pname); } if (reply.type == SCEP_MIME_GETCA_RA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ write_ca_ra(&reply); } /* Read payload as DER X.509 object: */ bp = BIO_new_mem_buf(reply.payload, reply.bytes); cacert = d2i_X509_bio(bp, NULL); /* Read and print certificate information */ if (!X509_digest(cacert, fp_alg, md, &n)) { ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag){ printf("%s: %s fingerprint: ", pname, OBJ_nid2sn(EVP_MD_type(fp_alg))); for (c = 0; c < (int)n; c++) { printf("%02X%c",md[c], (c + 1 == (int)n) ?'\n':':'); } } /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp,c_char , "w"))) #else if (!(fp = fopen(c_char, "w"))) #endif { fprintf(stderr, "%s: cannot open CA file for " "writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp, c_char) != 1) { fprintf(stderr, "%s: error while writing CA " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) printf("%s: CA certificate written as %s\n", pname, c_char); (void)fclose(fp); pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETNEXTCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETNEXTCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting nextCA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { if(v_flag){ fprintf(stderr, "%s: error while sending " "message\n", pname); fprintf(stderr, "%s: getnextCA might be not available" "\n", pname); } exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "there is no nextCA available\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if(d_flag) printf("%s: valid response from server\n", pname); if (reply.type == SCEP_MIME_GETNEXTCA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ //write_ca_ra(&reply); /* Set the whole struct as 0 */ memset(&scep_t, 0, sizeof(scep_t)); scep_t.reply_payload = reply.payload; scep_t.reply_len = reply.bytes; scep_t.request_type = SCEP_MIME_GETNEXTCA; pkcs7_verify_unwrap(&scep_t , C_char); //pkcs7_unwrap(&scep_t); } /* Get certs */ p7 = *(scep_t.reply_p7); nextcara = scep_t.reply_p7->d.sign->cert; if (v_flag) { printf ("verify and unwrap: found %d cert(s)\n", sk_X509_num(nextcara)); } for (i = 0; i < sk_X509_num(nextcara); i++) { char buffer[1024]; char name[1024]; memset(buffer, 0, 1024); memset(name, 0, 1024); cert = sk_X509_value(nextcara, i); if (v_flag) { printf("%s: found certificate with\n" " subject: '%s'\n", pname, X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer))); printf(" issuer: %s\n", X509_NAME_oneline(X509_get_issuer_name(cert), buffer, sizeof(buffer))); } /* Create name */ snprintf(name, 1024, "%s-%d", c_char, i); /* Write PEM-formatted file: */ if (!(fp = fopen(name, "w"))) { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); } if (v_flag) printf("%s: writing cert\n", pname); if (d_flag) PEM_write_X509(stdout, cert); if (PEM_write_X509(fp, cert) != 1) { fprintf(stderr, "%s: error while writing certificate " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } if(v_flag) printf("%s: certificate written as %s\n", pname, name); (void)fclose(fp); } pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETCERT: case SCEP_OPERATION_GETCRL: /* Read local certificate */ if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n", pname); exit (SCEP_PKISTATUS_FILE); } read_cert(&localcert, l_char); case SCEP_OPERATION_ENROLL: /* * Read in CA cert, private key and certificate * request in global variables. */ read_ca_cert(); if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n", pname); exit (SCEP_PKISTATUS_FILE); } if(scep_conf != NULL) { sscep_engine_read_key_new(&rsa, k_char, scep_t.e); } else { read_key(&rsa, k_char); } if ((K_flag && !O_flag) || (!K_flag && O_flag)) { fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname); exit (SCEP_PKISTATUS_FILE); } if (K_flag) { //TODO auf hwcrhk prfen? if(scep_conf != NULL) { sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e); } else { read_key(&renewal_key, K_char); } } if (O_flag) { read_cert(&renewal_cert, O_char); } if (operation_flag == SCEP_OPERATION_ENROLL) { read_request(); scep_t.transaction_id = key_fingerprint(request); if (v_flag) { printf("%s: Read request with transaction id: %s\n", pname, scep_t.transaction_id); } } if (operation_flag != SCEP_OPERATION_ENROLL) goto not_enroll; if (! O_flag) { if (v_flag) fprintf(stdout, "%s: generating selfsigned " "certificate\n", pname); new_selfsigned(&scep_t); } else { /* Use existing certificate */ scep_t.signercert = renewal_cert; scep_t.signerkey = renewal_key; } /* Write the selfsigned certificate if requested */ if (L_flag) { /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp, L_char, "w"))) { #else if (!(fp = fopen(L_char, "w"))) { #endif fprintf(stderr, "%s: cannot open " "file for writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp,scep_t.signercert) != 1) { fprintf(stderr, "%s: error while " "writing certificate file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } printf("%s: selfsigned certificate written " "as %s\n", pname, L_char); (void)fclose(fp); } /* Write issuer name and subject (GetCertInitial): */ if (!(scep_t.ias_getcertinit->subject = X509_REQ_get_subject_name(request))) { fprintf(stderr, "%s: error getting subject " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } not_enroll: if (!(scep_t.ias_getcertinit->issuer = X509_get_issuer_name(cacert))) { fprintf(stderr, "%s: error getting issuer " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* Write issuer name and serial (GETC{ert,rl}): */ scep_t.ias_getcert->issuer = scep_t.ias_getcertinit->issuer; scep_t.ias_getcrl->issuer = scep_t.ias_getcertinit->issuer; if (!(scep_t.ias_getcrl->serial = X509_get_serialNumber(cacert))) { fprintf(stderr, "%s: error getting serial " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* User supplied serial number */ if (s_flag) { BIGNUM *bn; ASN1_INTEGER *ai; int len = BN_dec2bn(&bn , s_char); if (!len || !(ai = BN_to_ASN1_INTEGER(bn, NULL))) { fprintf(stderr, "%s: error converting serial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_SS); } scep_t.ias_getcert->serial = ai; } break; } switch(operation_flag) { case SCEP_OPERATION_ENROLL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_ENROLL\n", pname); /* Resum mode: set GetCertInitial */ if (R_flag) { if (n_num == 0) exit (SCEP_PKISTATUS_SUCCESS); printf("%s: requesting certificate (#1)\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERTINIT; count++; } else { printf("%s: sending certificate request\n", pname); scep_t.request_type = SCEP_REQUEST_PKCSREQ; } break; case SCEP_OPERATION_GETCERT: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCERT\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERT; printf("%s: requesting certificate\n",pname); break; case SCEP_OPERATION_GETCRL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCRL\n", pname); scep_t.request_type = SCEP_REQUEST_GETCRL; printf("%s: requesting crl\n",pname); break; } /* Enter polling loop */ while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) { /* create payload */ pkcs7_wrap(&scep_t); /* URL-encode */ p = url_encode((char *)scep_t.request_payload, scep_t.request_len); /*Test mode print SCEP request and don't send it*/ if(m_flag){ /* Write output file : */ #ifdef WIN32 if ((fopen_s(&fp, m_char, "w"))) #else if (!(fp = fopen(m_char, "w"))) #endif { fprintf(stderr, "%s: cannot open output file for " "writing\n", m_char); }else { printf("%s: writing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(fp, scep_t.request_p7); } //printf("Print SCEP Request:\n %s\n",scep_t.request_payload); return 0; } /* Forge the HTTP message */ /* snprintf(http_string, sizeof(http_string), "GET %s%s?operation=" "PKIOperation&message=" "%s HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p);*/ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,p, M_char); } if (d_flag) fprintf(stdout, "%s: scep msg: %s", pname, http_string); /* send http */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } /* Verisign Onsite returns strange reply... * XXXXXXXXXXXXXXXXXXX */ if ((reply.status == 200) && (reply.payload == NULL)) { /* scep_t.pki_status = SCEP_PKISTATUS_PENDING; break; */ exit (SCEP_PKISTATUS_ERROR); } printf("%s: valid response from server\n", pname); /* Check payload */ scep_t.reply_len = reply.bytes; scep_t.reply_payload = (unsigned char *)reply.payload; pkcs7_unwrap(&scep_t); pkistatus = scep_t.pki_status; switch(scep_t.pki_status) { case SCEP_PKISTATUS_SUCCESS: break; case SCEP_PKISTATUS_PENDING: /* Check time limits */ if (((t_num * count) >= T_num) || (count > n_num)) { exit (pkistatus); } scep_t.request_type = SCEP_REQUEST_GETCERTINIT; /* Wait for poll interval */ if (v_flag) printf("%s: waiting for %d secs\n", pname, t_num); sleep(t_num); printf("%s: requesting certificate " "(#%d)\n", pname, count); /* Add counter */ count++; break; case SCEP_PKISTATUS_FAILURE: /* Handle failure */ switch (scep_t.fail_info) { case SCEP_FAILINFO_BADALG: exit (SCEP_PKISTATUS_BADALG); case SCEP_FAILINFO_BADMSGCHK: exit (SCEP_PKISTATUS_BADMSGCHK); case SCEP_FAILINFO_BADREQ: exit (SCEP_PKISTATUS_BADREQ); case SCEP_FAILINFO_BADTIME: exit (SCEP_PKISTATUS_BADTIME); case SCEP_FAILINFO_BADCERTID: exit (SCEP_PKISTATUS_BADCERTID); /* Shouldn't be there... */ default: exit (SCEP_PKISTATUS_ERROR); } default: fprintf(stderr, "%s: unknown " "pkiStatus\n", pname); exit (SCEP_PKISTATUS_ERROR); } } /* We got SUCCESS, analyze the reply */ switch (scep_t.request_type) { /* Local certificate */ case SCEP_REQUEST_PKCSREQ: case SCEP_REQUEST_GETCERTINIT: write_local_cert(&scep_t); break; /* Other end entity certificate */ case SCEP_REQUEST_GETCERT: write_other_cert(&scep_t); break; break; /* CRL */ case SCEP_REQUEST_GETCRL: write_crl(&scep_t); break; } //TODO //richtiger ort für disable?? // if(e){ // ENGINE_finish(*e); // ENGINE_free(*e); // hwEngine = NULL; // ENGINE_cleanup(); // } // return (pkistatus); } void usage() { fprintf(stdout, "\nsscep version %s\n\n" , VERSION); fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n" "\nAvailable OPERATIONs are\n" " getca Get CA/RA certificate(s)\n" " getnextca Get next CA/RA certificate(s)\n" " enroll Enroll certificate\n" " getcert Query certificate\n" " getcrl Query CRL\n" "\nGeneral OPTIONS\n" " -u <url> SCEP server URL\n" " -p <host:port> Use proxy server at host:port\n" " -M <string> Monitor Information String name=value&name=value ...\n" " -g Enable Engine support\n" " -h Keyforme=ID. \n"//TODO " -f <file> Use configuration file\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -E <name> PKCS#7 encryption algorithm (des|3des|blowfish|aes)\n" " -S <name> PKCS#7 signature algorithm (md5|sha1)\n" " -v Verbose operation\n" " -d Debug (even more verbose operation)\n" "\nOPTIONS for OPERATION getca are\n" " -i <string> CA identifier string\n" " -F <name> Fingerprint algorithm\n" "\nOPTIONS for OPERATION getnextca are\n" " -C <file> Local certificate chain file for signature verification in PEM format \n" " -F <name> Fingerprint algorithm\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -w <file> Write signer certificate in file (optional) \n" "\nOPTIONS for OPERATION enroll are\n" " -k <file> Private key file\n" " -r <file> Certificate request file\n" " -K <file> Signature private key file, use with -O\n" " -O <file> Signature certificate (used instead of self-signed)\n" " -l <file> Write enrolled certificate in file\n" " -e <file> Use different CA cert for encryption\n" " -L <file> Write selfsigned certificate in file\n" " -t <secs> Polling interval in seconds\n" " -T <secs> Max polling time in seconds\n" " -n <count> Max number of GetCertInitial requests\n" " -R Resume interrupted enrollment\n" "\nOPTIONS for OPERATION getcert are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -s <number> Certificate serial number\n" " -w <file> Write certificate in file\n" "\nOPTIONS for OPERATION getcrl are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -w <file> Write CRL in file\n\n", pname); exit(0); }
/* Init necessary structures for SSL in WebIf*/ SSL_CTX *SSL_Webif_Init(void) { SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); ERR_load_SSL_strings(); SSL_CTX *ctx; static const char *cs_cert = "oscam.pem"; if(pthread_key_create(&getssl, NULL)) { cs_log("Could not create getssl"); } // set locking callbacks for SSL int32_t i, num = CRYPTO_num_locks(); lock_cs = (CS_MUTEX_LOCK *) OPENSSL_malloc(num * sizeof(CS_MUTEX_LOCK)); for(i = 0; i < num; ++i) { cs_lock_create(&lock_cs[i], "ssl_lock_cs", 10000); } /* static lock callbacks */ CRYPTO_set_id_callback(SSL_id_function); CRYPTO_set_locking_callback(SSL_locking_function); /* dynamic lock callbacks */ CRYPTO_set_dynlock_create_callback(SSL_dyn_create_function); CRYPTO_set_dynlock_lock_callback(SSL_dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(SSL_dyn_destroy_function); if(cfg.http_force_sslv3) { ctx = SSL_CTX_new(SSLv3_server_method()); #ifdef SSL_CTX_clear_options SSL_CTX_clear_options(ctx, SSL_OP_ALL); //we CLEAR all bug workarounds! This is for security reason #else cs_log("WARNING: You enabled to force sslv3 but your system does not support to clear the ssl workarounds! SSL security will be reduced!"); #endif SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); // we force SSL v3 ! SSL_CTX_set_cipher_list(ctx, SSL_TXT_RC4); } else { ctx = SSL_CTX_new(SSLv23_server_method()); } char path[128]; if(!cfg.http_cert) { get_config_filename(path, sizeof(path), cs_cert); } else { cs_strncpy(path, cfg.http_cert, sizeof(path)); } if(!ctx) { ERR_print_errors_fp(stderr); return NULL; } if(SSL_CTX_use_certificate_file(ctx, path, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); return NULL; } if(SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); return NULL; } if(!SSL_CTX_check_private_key(ctx)) { cs_log("SSL: Private key does not match the certificate public key"); return NULL; } cs_log("load ssl certificate file %s", path); return ctx; }
int krx_ssl_ctx_init(krx* k, const char* keyname) { int r = 0; /* create a new context using DTLS */ k->ctx = SSL_CTX_new(DTLSv1_method()); if(!k->ctx) { printf("Error: cannot create SSL_CTX.\n"); ERR_print_errors_fp(stderr); return -1; } /* set our supported ciphers */ r = SSL_CTX_set_cipher_list(k->ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); if(r != 1) { printf("Error: cannot set the cipher list.\n"); ERR_print_errors_fp(stderr); return -2; } /* the client doesn't have to send it's certificate */ SSL_CTX_set_verify(k->ctx, SSL_VERIFY_PEER, krx_ssl_verify_peer); /* enable srtp */ r = SSL_CTX_set_tlsext_use_srtp(k->ctx, "SRTP_AES128_CM_SHA1_80"); if(r != 0) { printf("Error: cannot setup srtp.\n"); ERR_print_errors_fp(stderr); return -3; } /* load key and certificate */ char certfile[1024]; char keyfile[1024]; sprintf(certfile, "./%s-cert.pem", keyname); sprintf(keyfile, "./%s-key.pem", keyname); /* certificate file; contains also the public key */ r = SSL_CTX_use_certificate_file(k->ctx, certfile, SSL_FILETYPE_PEM); if(r != 1) { printf("Error: cannot load certificate file.\n"); ERR_print_errors_fp(stderr); return -4; } /* load private key */ r = SSL_CTX_use_PrivateKey_file(k->ctx, keyfile, SSL_FILETYPE_PEM); if(r != 1) { printf("Error: cannot load private key file.\n"); ERR_print_errors_fp(stderr); return -5; } /* check if the private key is valid */ r = SSL_CTX_check_private_key(k->ctx); if(r != 1) { printf("Error: checking the private key failed. \n"); ERR_print_errors_fp(stderr); return -6; } sprintf(k->name, "+ %s", keyname); return 0; }
int main(int argc, char *argv[]) { BIO *sbio; SSL_CTX *ssl_ctx; SSL *ssl; X509 *server_cert; // Initialize OpenSSL OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_load_error_strings(); // Check OpenSSL PRNG if(RAND_status() != 1) { fprintf(stderr, "OpenSSL PRNG not seeded with enough data."); goto error_1; } ssl_ctx = SSL_CTX_new(TLSv1_client_method()); // Enable certificate validation SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); // Configure the CA trust store to be used if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) { fprintf(stderr, "Couldn't load certificate trust store.\n"); goto error_2; } // Only support secure cipher suites if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1) goto error_2; // Create the SSL connection sbio = BIO_new_ssl_connect(ssl_ctx); BIO_get_ssl(sbio, &ssl); if(!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto error_3; } // Do the SSL handshake BIO_set_conn_hostname(sbio, TARGET_SERVER); if(SSL_do_handshake(ssl) <= 0) { // SSL Handshake failed long verify_err = SSL_get_verify_result(ssl); if (verify_err != X509_V_OK) { // It failed because the certificate chain validation failed fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err)); } else { // It failed for another reason ERR_print_errors_fp(stderr); } goto error_3; } // Recover the server's certificate server_cert = SSL_get_peer_certificate(ssl); if (server_cert == NULL) { // The handshake was successful although the server did not provide a certificate // Most likely using an insecure anonymous cipher suite... get out! goto error_4; } // Validate the hostname if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) { fprintf(stderr, "Hostname validation failed.\n"); goto error_5; } // Hostname validation succeeded; we can start sending data send_http_get_and_print(sbio); error_5: X509_free(server_cert); error_4: BIO_ssl_shutdown(sbio); error_3: BIO_free_all(sbio); error_2: SSL_CTX_free(ssl_ctx); error_1: // OpenSSL cleanup EVP_cleanup(); ERR_free_strings(); return 0; }
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) { EC_KEY *a=NULL; EC_KEY *b=NULL; BIGNUM *x_a=NULL, *y_a=NULL, *x_b=NULL, *y_b=NULL; char buf[12]; unsigned char *abuf=NULL,*bbuf=NULL; int i,alen,blen,aout,bout,ret=0; const EC_GROUP *group; a = EC_KEY_new_by_curve_name(nid); b = EC_KEY_new_by_curve_name(nid); if (a == NULL || b == NULL) goto err; group = EC_KEY_get0_group(a); if ((x_a=BN_new()) == NULL) goto err; if ((y_a=BN_new()) == NULL) goto err; if ((x_b=BN_new()) == NULL) goto err; if ((y_b=BN_new()) == NULL) goto err; BIO_puts(out,"Testing key generation with "); BIO_puts(out,text); #ifdef NOISY BIO_puts(out,"\n"); #else (void)BIO_flush(out); #endif if (!EC_KEY_generate_key(a)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; } #ifdef NOISY BIO_puts(out," pri 1="); BN_print(out,a->priv_key); BIO_puts(out,"\n pub 1="); BN_print(out,x_a); BIO_puts(out,","); BN_print(out,y_a); BIO_puts(out,"\n"); #else BIO_printf(out," ."); (void)BIO_flush(out); #endif if (!EC_KEY_generate_key(b)) goto err; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } else { if (!EC_POINT_get_affine_coordinates_GF2m(group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; } #ifdef NOISY BIO_puts(out," pri 2="); BN_print(out,b->priv_key); BIO_puts(out,"\n pub 2="); BN_print(out,x_b); BIO_puts(out,","); BN_print(out,y_b); BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif alen=KDF1_SHA1_len; abuf=(unsigned char *)OPENSSL_malloc(alen); aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1); #ifdef NOISY BIO_puts(out," key1 ="); for (i=0; i<aout; i++) { TINYCLR_SSL_SPRINTF(buf,"%02X",abuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif blen=KDF1_SHA1_len; bbuf=(unsigned char *)OPENSSL_malloc(blen); bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1); #ifdef NOISY BIO_puts(out," key2 ="); for (i=0; i<bout; i++) { TINYCLR_SSL_SPRINTF(buf,"%02X",bbuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); #else BIO_printf(out,"."); (void)BIO_flush(out); #endif if ((aout < 4) || (bout != aout) || (TINYCLR_SSL_MEMCMP(abuf,bbuf,aout) != 0)) { #ifndef NOISY BIO_printf(out, " failed\n\n"); BIO_printf(out, "key a:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(a)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_a); BIO_printf(out, ","); BN_print(out, y_a); BIO_printf(out, "\nkey b:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(b)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_b); BIO_printf(out, ","); BN_print(out, y_b); BIO_printf(out, "\n"); BIO_printf(out, "generated key a: "); for (i=0; i<bout; i++) { TINYCLR_SSL_SPRINTF(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_printf(out, "\n"); BIO_printf(out, "generated key b: "); for (i=0; i<aout; i++) { TINYCLR_SSL_SPRINTF(buf, "%02X", abuf[i]); BIO_puts(out,buf); } BIO_printf(out, "\n"); #endif TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"Error in ECDH routines\n"); ret=0; } else { #ifndef NOISY BIO_printf(out, " ok\n"); #endif ret=1; } err: ERR_print_errors_fp(OPENSSL_TYPE__FILE_STDERR); if (abuf != NULL) OPENSSL_free(abuf); if (bbuf != NULL) OPENSSL_free(bbuf); if (x_a) BN_free(x_a); if (y_a) BN_free(y_a); if (x_b) BN_free(x_b); if (y_b) BN_free(y_b); if (b) EC_KEY_free(b); if (a) EC_KEY_free(a); return(ret); }
void handle_error(const char *file, int linenum, const char *msg) { fprintf(stderr, "*** %s:%i %s\n", file, linenum, msg); ERR_print_errors_fp(stderr); exit(-1); }
int main(int argc, char *argv[]) { char *port = "*:4433"; BIO *ssl_bio, *tmp; SSL_CTX *ctx; SSL_CONF_CTX *cctx; char buf[512]; BIO *in = NULL; int ret = 1, i; char **args = argv + 1; int nargs = argc - 1; SSL_load_error_strings(); /* Add ciphers and message digests */ OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(SSLv23_server_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); 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 err; } if (rv < 0) { fprintf(stderr, "Error in command %s\n", *args); ERR_print_errors_fp(stderr); goto err; } /* If rv > 0 we processed something so proceed to next arg */ if (rv > 0) continue; /* Otherwise application specific argument processing */ if (!strcmp(*args, "-port")) { port = args[1]; if (port == NULL) { fprintf(stderr, "Missing -port argument\n"); goto err; } args += 2; nargs -= 2; continue; } else { fprintf(stderr, "Unknown argument %s\n", *args); goto err; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } #ifdef ITERATE_CERTS /* * Demo of how to iterate over all certificates in an SSL_CTX structure. */ { X509 *x; int rv; rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); while (rv) { X509 *x = SSL_CTX_get0_certificate(ctx); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); printf("\n"); rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); } fflush(stdout); } #endif /* 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); 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; for (;;) { 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); }
void secure_and_send(int client_fd, char* read_pipe, char* write_pipe, int index, FILE* d_out){ BIO* bio; SSL* ssl; SSL_CTX* ctx; /*init ssl library*/ SSL_library_init(); ERR_load_BIO_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); /* Set up the SSL context */ ctx = SSL_CTX_new(SSLv23_client_method()); /* Load the trust store */ if(! SSL_CTX_load_verify_locations(ctx, "cacerts.pem", NULL)) { fprintf(stderr, "Error loading trust store\n"); ERR_print_errors_fp(stderr); SSL_CTX_free(ctx); return; } /* Setup the connection */ bio = BIO_new_ssl_connect(ctx); /* Set the SSL_MODE_AUTO_RETRY flag */ BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create and setup the connection */ char host[LINE]; sprintf(host,"%s:%s",safe_host[index],safe_port[index]); BIO_set_conn_hostname(bio, safe_host[index]); BIO_set_conn_port(bio,safe_port[index]); if(BIO_do_connect(bio) <= 0) { fprintf(stderr, "Error attempting to connect\n"); ERR_print_errors_fp(stderr); BIO_free_all(bio); SSL_CTX_free(ctx); return; } /* Check the certificate */ if(SSL_get_verify_result(ssl) != X509_V_OK) { fprintf(stderr, "Certificate verification error: %lu\n", SSL_get_verify_result(ssl)); BIO_free_all(bio); SSL_CTX_free(ctx); return; } /* Send the request */ BIO_write(bio, read_pipe, strlen(read_pipe)); /* Read in the response */ for(;;) { int p = BIO_read(bio, write_pipe, PIPE_MAX); if(p <= 0) break; p = write(client_fd,write_pipe,p); } /* Close the connection and free the context */ BIO_free_all(bio); SSL_CTX_free(ctx); close(client_fd); fclose(d_out); return; }
void handleErrors(void) { ERR_print_errors_fp(stderr); abort(); }
int main(int argc, char **argv) { FILE *fp; // Bucket to keep pids in. int process_pool[POOL_SIZE]; // Count of pids we are wait()ing on. int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0; int gid = 0, client_sock = 0, sock = 0, port = DEFAULT_PORT, ret = 0; char *dir = DEFAULTDIR; char *group = GROUPGLOBAL; char *server_cert = NULL; char *server_key = NULL; char *ca_cert = NULL; char buf[4096 +1]; SSL_CTX *ctx; SSL *ssl; char srcip[IPSIZE +1]; struct sockaddr_in _nc; socklen_t _ncl; /* Initializing some variables */ memset(srcip, '\0', IPSIZE + 1); memset(process_pool, 0x0, POOL_SIZE); bio_err = 0; /* Setting the name */ OS_SetName(ARGV0); /* add an option to use the ip on the socket to tie the name to a specific address */ while((c = getopt(argc, argv, "Vdhtig:D:m:p:v:x:k:")) != -1) { switch(c){ case 'V': print_version(); break; case 'h': help_authd(); break; case 'd': nowDebug(); break; case 'i': use_ip_address = 1; break; case 'g': if(!optarg) ErrorExit("%s: -g needs an argument",ARGV0); group = optarg; break; case 'D': if(!optarg) ErrorExit("%s: -D needs an argument",ARGV0); dir = optarg; break; case 't': test_config = 1; break; case 'p': if(!optarg) ErrorExit("%s: -%c needs an argument",ARGV0, c); port = atoi(optarg); if(port <= 0 || port >= 65536) { ErrorExit("%s: Invalid port: %s", ARGV0, optarg); } break; case 'v': if (!optarg) ErrorExit("%s: -%c needs an argument", ARGV0, c); ca_cert = optarg; break; case 'x': if (!optarg) ErrorExit("%s: -%c needs an argument", ARGV0, c); server_cert = optarg; break; case 'k': if (!optarg) ErrorExit("%s: -%c needs an argument", ARGV0, c); server_key = optarg; break; default: help_authd(); break; } } /* Starting daemon -- NB: need to double fork and setsid */ debug1(STARTED_MSG,ARGV0); /* Check if the user/group given are valid */ gid = Privsep_GetGroup(group); if(gid < 0) ErrorExit(USER_ERROR,ARGV0,"",group); /* Exit here if test config is set */ if(test_config) exit(0); /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* chrooting -- TODO: this isn't a chroot. Should also close unneeded open file descriptors (like stdin/stdout)*/ if(chdir(dir) == -1) { ErrorExit(CHDIR_ERROR, ARGV0, dir); } /* Signal manipulation */ StartSIG(ARGV0); /* Creating PID files */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); fp = fopen(KEYSFILE_PATH,"a"); if(!fp) { merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH); exit(1); } /* Starting SSL */ ctx = os_ssl_keys(1, dir, server_cert, server_key, ca_cert); if(!ctx) { merror("%s: ERROR: SSL error. Exiting.", ARGV0); exit(1); } /* Connecting via TCP */ sock = OS_Bindporttcp(port, NULL, 0); if(sock <= 0) { merror("%s: Unable to bind to port %d", ARGV0, port); exit(1); } fcntl(sock, F_SETFL, O_NONBLOCK); debug1("%s: DEBUG: Going into listening mode.", ARGV0); while(1) { // no need to completely pin the cpu, 100ms should be fast enough usleep(100*1000); // Only check process-pool if we have active processes if(active_processes > 0){ for (i = 0; i < POOL_SIZE; i++) { int rv = 0; status = 0; if (process_pool[i]) { rv = waitpid(process_pool[i], &status, WNOHANG); if (rv != 0){ debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]); process_pool[i] = 0; active_processes = active_processes - 1; } } } } memset(&_nc, 0, sizeof(_nc)); _ncl = sizeof(_nc); if((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0){ if (active_processes >= POOL_SIZE) { merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0); break; } pid = fork(); if(pid) { active_processes = active_processes + 1; close(client_sock); for (i = 0; i < POOL_SIZE; i++) { if (! process_pool[i]) { process_pool[i] = pid; break; } } } else { strncpy(srcip, inet_ntoa(_nc.sin_addr),IPSIZE -1); char *agentname = NULL; ssl = SSL_new(ctx); SSL_set_fd(ssl, client_sock); do { ret = SSL_accept(ssl); if (ssl_error(ssl, ret)) clean_exit(ctx, client_sock); } while (ret <= 0); verbose("%s: INFO: New connection from %s", ARGV0, srcip); do { ret = SSL_read(ssl, buf, sizeof(buf)); if (ssl_error(ssl, ret)) clean_exit(ctx, client_sock); } while (ret <= 0); int parseok = 0; if(strncmp(buf, "OSSEC A:'", 9) == 0) { char *tmpstr = buf; agentname = tmpstr + 9; tmpstr += 9; while(*tmpstr != '\0') { if(*tmpstr == '\'') { *tmpstr = '\0'; verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip); parseok = 1; break; } tmpstr++; } } if(parseok == 0) { merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip); } else { int acount = 2; char fname[2048 +1]; char response[2048 +1]; char *finalkey = NULL; response[2048] = '\0'; fname[2048] = '\0'; if(!OS_IsValidName(agentname)) { merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip); snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } /* Checking for a duplicated names. */ strncpy(fname, agentname, 2048); while(NameExist(fname)) { snprintf(fname, 2048, "%s%d", agentname, acount); acount++; if(acount > 256) { merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname); snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } } agentname = fname; /* Adding the new agent. */ if (use_ip_address) { finalkey = OS_AddNewAgent(agentname, srcip, NULL); } else { finalkey = OS_AddNewAgent(agentname, NULL, NULL); } if(!finalkey) { merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname); snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } snprintf(response, 2048,"OSSEC K:'%s'\n\n", finalkey); verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip); ret = SSL_write(ssl, response, strlen(response)); if(ret < 0) { merror("%s: ERROR: SSL write error (%d)", ARGV0, ret); merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname); ERR_print_errors_fp(stderr); } else { verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip); } } clean_exit(ctx, client_sock); } } } /* Shutdown the socket */ clean_exit(ctx, sock); return (0); }
int main(int argc, char *argv[]) { char *port = NULL; BIO *ssl_bio, *tmp; SSL_CTX *ctx; char buf[512]; int ret = 1, i; if (argc <= 1) port = "*:4433"; else port = argv[1]; signal(SIGINT, close_up); 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_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) 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); 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; for (;;) { 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); }
/** * \brief Input plugin initializtion function * * \param[in] params XML with input parameters * \param[out] config Sets source and destination IP, destination port. * \return 0 on success, nonzero else. */ int input_init(char *params, void **config) { /* necessary structures */ struct addrinfo *addrinfo = NULL, hints; struct plugin_conf *conf = NULL; char *port = NULL, *address = NULL; int ai_family = AF_INET6; /* IPv6 is default */ char dst_addr[INET6_ADDRSTRLEN]; int ret, ipv6_only = 0, retval = 0, yes = 1; /* yes is for setsockopt */ /* 1 when using default port - don't free memory */ int def_port = 0; #ifdef TLS_SUPPORT SSL_CTX *ctx = NULL; /* SSL context structure */ SSL **ssl_list = NULL; /* list of SSL connection structures */ xmlNode *cur_node_parent; #endif /* parse params */ xmlDoc *doc = NULL; xmlNode *root_element = NULL; xmlNode *cur_node = NULL; /* allocate plugin_conf structure */ conf = calloc(1, sizeof(struct plugin_conf)); if (conf == NULL) { MSG_ERROR(msg_module, "Cannot allocate memory for config structure: %s", strerror(errno)); retval = 1; goto out; } if (!enlarge_sock_addresses(conf)) { MSG_ERROR(msg_module, "Cannot initialize array for socket address"); retval = 1; goto out; } /* empty the master set */ FD_ZERO(&conf->master); /* parse xml string */ doc = xmlParseDoc(BAD_CAST params); if (doc == NULL) { MSG_ERROR(msg_module, "Cannot parse configuration file"); retval = 1; goto out; } /* get the root element node */ root_element = xmlDocGetRootElement(doc); if (root_element == NULL) { MSG_ERROR(msg_module, "Cannot get document root element"); retval = 1; goto out; } /* check that we have the right config xml, BAD_CAST is (xmlChar *) cast defined by libxml */ if (!xmlStrEqual(root_element->name, BAD_CAST "tcpCollector")) { MSG_ERROR(msg_module, "Expecting tcpCollector root element; got %s", root_element->name); retval = 1; goto out; } /* go over all elements */ for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) { #ifdef TLS_SUPPORT /* check whether we want to enable transport layer security */ if (xmlStrEqual(cur_node->name, BAD_CAST "transportLayerSecurity")) { MSG_INFO(msg_module, "TLS enabled"); conf->tls = 1; /* TLS enabled */ cur_node_parent = cur_node; /* TLS configuration options */ for (cur_node = cur_node->xmlChildrenNode; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE && cur_node->children != NULL && cur_node->children->content != NULL) { int tmp_val_len = strlen((char *) cur_node->children->content) + 1; char *tmp_val = malloc(sizeof(char) * tmp_val_len); if (!tmp_val) { MSG_ERROR(msg_module, "Cannot allocate memory: %s", strerror(errno)); retval = 1; goto out; } strncpy_safe(tmp_val, (char *)cur_node->children->content, tmp_val_len); if (xmlStrEqual(cur_node->name, BAD_CAST "localCAfile")) { /* location of the CA certificate */ conf->ca_cert_file = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "localServerCert")) { /* server's certificate */ conf->server_cert_file = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "localServerCertKey")) { /* server's private key */ conf->server_pkey_file = tmp_val; } else { /* unknown option */ MSG_WARNING(msg_module, "Unknown configuration option: %s", cur_node->name); free(tmp_val); } } } cur_node = cur_node_parent; continue; } #else /* user wants TLS, but collector was compiled without it */ if (xmlStrEqual(cur_node->name, BAD_CAST "transportLayerSecurity")) { /* user wants to enable TLS, but collector was compiled without it */ MSG_WARNING(msg_module, "Collector was compiled without TLS support"); continue; } #endif if (cur_node->type == XML_ELEMENT_NODE && cur_node->children != NULL) { /* copy value to memory - don't forget the terminating zero */ int tmp_val_len = strlen((char *) cur_node->children->content) + 1; char *tmp_val = malloc(sizeof(char) * tmp_val_len); /* this is not a preferred cast, but we really want to use plain chars here */ if (tmp_val == NULL) { MSG_ERROR(msg_module, "Cannot allocate memory: %s", strerror(errno)); retval = 1; goto out; } strncpy_safe(tmp_val, (char *)cur_node->children->content, tmp_val_len); if (xmlStrEqual(cur_node->name, BAD_CAST "localPort") && port == NULL) { /* set local port */ port = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "localIPAddress") && address == NULL) { /* set local address */ address = tmp_val; /* save following configuration to input_info */ } else if (xmlStrEqual(cur_node->name, BAD_CAST "templateLifeTime")) { conf->info.template_life_time = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "optionsTemplateLifeTime")) { conf->info.options_template_life_time = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "templateLifePacket")) { conf->info.template_life_packet = tmp_val; } else if (xmlStrEqual(cur_node->name, BAD_CAST "optionsTemplateLifePacket")) { conf->info.options_template_life_packet = tmp_val; } else { /* unknown parameter, ignore */ /* Free the tmp_val for unknown elements */ free(tmp_val); } } } /* set default port if none given */ if (port == NULL) { port = DEFAULT_PORT; def_port = 1; } #ifdef TLS_SUPPORT if (conf->tls) { /* use default options if not specified in configuration file */ if (conf->ca_cert_file == NULL) { conf->ca_cert_file = strdup(DEFAULT_CA_FILE); } if (conf->server_cert_file == NULL) { conf->server_cert_file = strdup(DEFAULT_SERVER_CERT_FILE); } if (conf->server_pkey_file == NULL) { conf->server_pkey_file = strdup(DEFAULT_SERVER_PKEY_FILE); } } #endif /* specify parameters of the connection */ memset (&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; /* TCP */ hints.ai_family = ai_family; /* select IPv4 or IPv6*/ hints.ai_flags = AI_V4MAPPED; /* we want to accept mapped addresses */ if (address == NULL) { hints.ai_flags |= AI_PASSIVE; /* no address given, listen on all local addresses */ } /* get server address */ if ((ret = getaddrinfo(address, port, &hints, &addrinfo)) != 0) { MSG_ERROR(msg_module, "getaddrinfo failed: %s", gai_strerror(ret)); retval = 1; goto out; } /* create socket */ conf->socket = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); /* Retry with IPv4 when the implementation does not support the specified address family */ if (conf->socket == -1 && errno == EAFNOSUPPORT && addrinfo->ai_family == AF_INET6) { addrinfo->ai_family = AF_INET; conf->socket = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); } if (conf->socket == -1) { /* End with error otherwise */ MSG_ERROR(msg_module, "Cannot create socket: %s", strerror(errno)); retval = 1; goto out; } /* allow IPv4 connections on IPv6 */ if ((addrinfo->ai_family == AF_INET6) && (setsockopt(conf->socket, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6_only, sizeof(ipv6_only)) == -1)) { MSG_WARNING(msg_module, "Cannot turn off socket option IPV6_V6ONLY; plugin may not accept IPv4 connections..."); } /* allow to reuse the address immediately */ if (setsockopt(conf->socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { MSG_WARNING(msg_module, "Cannot turn on socket reuse option; it may take a while before collector can be restarted"); } /* bind socket to address */ if (bind(conf->socket, addrinfo->ai_addr, addrinfo->ai_addrlen) != 0) { MSG_ERROR(msg_module, "Cannot bind socket: %s", strerror(errno)); retval = 1; goto out; } /* this is a listening socket */ if (listen(conf->socket, BACKLOG) == -1) { MSG_ERROR(msg_module, "Cannot listen on socket: %s", strerror(errno)); retval = 1; goto out; } #ifdef TLS_SUPPORT if (conf->tls) { /* configure TLS */ /* initialize library */ SSL_load_error_strings(); SSL_library_init(); /* create CTX structure for TLS */ ctx = SSL_CTX_new(TLSv1_server_method()); if (!ctx) { MSG_ERROR(msg_module, "Cannot create CTX structure"); ERR_print_errors_fp(stderr); retval = 1; goto out; } /* load server certificate into the CTX structure */ ret = SSL_CTX_use_certificate_file(ctx, conf->server_cert_file, SSL_FILETYPE_PEM); if (ret != 1) { MSG_ERROR(msg_module, "Unable to load server's certificate from %s", conf->server_cert_file); ERR_print_errors_fp(stderr); retval = 1; goto out; } /* load private keys into the CTX structure */ SSL_CTX_use_PrivateKey_file(ctx, conf->server_pkey_file, SSL_FILETYPE_PEM); if (ret <= 0) { MSG_ERROR(msg_module, "Unable to load server's private key from %s", conf->server_pkey_file); ERR_print_errors_fp(stderr); retval = 1; goto out; } /* set peer certificate verification parameters */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); ssl_list = (SSL **) malloc(sizeof(SSL *) * DEFAULT_SIZE_SSL_LIST); if (ssl_list == NULL) { MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__); retval = 1; goto out; } memset(ssl_list, 0, DEFAULT_SIZE_SSL_LIST * sizeof(SSL *)); conf->ssl_list_size = DEFAULT_SIZE_SSL_LIST; conf->ctx = ctx; conf->ssl_list = ssl_list; } #endif /* TLS */ /* fill in general information */ conf->info.type = SOURCE_TYPE_TCP; conf->info.dst_port = atoi(port); if (addrinfo->ai_family == AF_INET) { /* IPv4 */ conf->info.l3_proto = 4; /* copy dst IPv4 address */ conf->info.dst_addr.ipv4.s_addr = ((struct sockaddr_in*) addrinfo->ai_addr)->sin_addr.s_addr; inet_ntop(AF_INET, &conf->info.dst_addr.ipv4, dst_addr, INET6_ADDRSTRLEN); } else { /* IPv6 */ conf->info.l3_proto = 6; /* copy dst IPv6 address */ int i; for (i=0; i<4;i++) { conf->info.dst_addr.ipv6.s6_addr32[i] = ((struct sockaddr_in6*) addrinfo->ai_addr)->sin6_addr.s6_addr32[i]; } inet_ntop(AF_INET6, &conf->info.dst_addr.ipv6, dst_addr, INET6_ADDRSTRLEN); } /* allocate memory for templates */ if (convert_init(TCP_PLUGIN, BUFF_LEN) != 0) { MSG_ERROR(msg_module, "malloc() for templates failed!"); retval = 1; goto out; } /* print info */ MSG_INFO(msg_module, "Input plugin listening on %s, port %s", dst_addr, port); /* start listening thread */ if (pthread_create(&listen_thread, NULL, &input_listen, (void *) conf) != 0) { MSG_ERROR(msg_module, "Failed to create listening thread"); retval = 1; goto out; } /* pass general information to the collector */ *config = (void*) conf; /* normal exit, all OK */ MSG_INFO(msg_module, "Plugin initialization completed successfully"); out: if (def_port == 0 && port != NULL) { /* free when memory was actually allocated*/ free(port); } if (address != NULL) { free(address); } if (addrinfo != NULL) { freeaddrinfo(addrinfo); } /* free the xml document */ if (doc != NULL) { xmlFreeDoc(doc); } /* free the global variables that may have been allocated by the xml parser */ xmlCleanupParser(); /* free input_info when error occured */ if (retval != 0 && conf != NULL) { if (conf->info.template_life_time != NULL) { free (conf->info.template_life_time); } if (conf->info.options_template_life_time != NULL) { free (conf->info.options_template_life_time); } if (conf->info.template_life_packet != NULL) { free (conf->info.template_life_packet); } if (conf->info.options_template_life_packet != NULL) { free (conf->info.options_template_life_packet); } free(conf); } #ifdef TLS_SUPPORT /* error occurs, clean up */ if ((retval != 0) && (conf != NULL)) { if (ssl_list) { free(ssl_list); } if (ctx) { SSL_CTX_free(ctx); } } #endif return retval; }
int main(int argc, char **argv) { BIO *sbio = NULL, *out = NULL; int i, len, rv; char tmpbuf[1024]; SSL_CTX *ctx = NULL; SSL_CONF_CTX *cctx = NULL; SSL *ssl = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; const char *connect_str = "localhost:4433"; long errline = -1; ERR_load_crypto_strings(); ERR_load_SSL_strings(); SSL_library_init(); conf = NCONF_new(NULL); if (NCONF_load(conf, "connect.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto end; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto end; } 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_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto end; } if (strcmp(cnf->name, "Connect") == 0) { connect_str = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto end; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* * 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); NCONF_free(conf); return 0; }
int main(int argc, char *argv[]) { BN_GENCB _cb; DH *a; DH *b = NULL; char buf[12]; unsigned char *abuf = NULL, *bbuf = NULL; int i, alen, blen, aout, bout, ret = 1; BIO *out; CRYPTO_malloc_debug_init(); CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); # ifdef OPENSSL_SYS_WIN32 CRYPTO_malloc_init(); # endif RAND_seed(rnd_seed, sizeof rnd_seed); out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE); BN_GENCB_set(&_cb, &cb, out); if (((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64, DH_GENERATOR_5, &_cb)) goto err; if (!DH_check(a, &i)) goto err; if (i & DH_CHECK_P_NOT_PRIME) BIO_puts(out, "p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) BIO_puts(out, "p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) BIO_puts(out, "unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) BIO_puts(out, "the g value is not a generator\n"); BIO_puts(out, "\np ="); BN_print(out, a->p); BIO_puts(out, "\ng ="); BN_print(out, a->g); BIO_puts(out, "\n"); b = DH_new(); if (b == NULL) goto err; b->p = BN_dup(a->p); b->g = BN_dup(a->g); if ((b->p == NULL) || (b->g == NULL)) goto err; /* Set a to run with normal modexp and b to use constant time */ a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME; b->flags |= DH_FLAG_NO_EXP_CONSTTIME; if (!DH_generate_key(a)) goto err; BIO_puts(out, "pri 1="); BN_print(out, a->priv_key); BIO_puts(out, "\npub 1="); BN_print(out, a->pub_key); BIO_puts(out, "\n"); if (!DH_generate_key(b)) goto err; BIO_puts(out, "pri 2="); BN_print(out, b->priv_key); BIO_puts(out, "\npub 2="); BN_print(out, b->pub_key); BIO_puts(out, "\n"); alen = DH_size(a); abuf = (unsigned char *)OPENSSL_malloc(alen); aout = DH_compute_key(abuf, b->pub_key, a); BIO_puts(out, "key1 ="); for (i = 0; i < aout; i++) { snprintf(buf, sizeof(buf), "%02X",abuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); blen = DH_size(b); bbuf = (unsigned char *)OPENSSL_malloc(blen); bout = DH_compute_key(bbuf, a->pub_key, b); BIO_puts(out, "key2 ="); for (i = 0; i < bout; i++) { snprintf(buf, sizeof(buf), "%02X",bbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { fprintf(stderr, "Error in DH routines\n"); ret = 1; } else ret = 0; err: ERR_print_errors_fp(stderr); if (abuf != NULL) OPENSSL_free(abuf); if (bbuf != NULL) OPENSSL_free(bbuf); if (b != NULL) DH_free(b); if (a != NULL) DH_free(a); BIO_free(out); # ifdef OPENSSL_SYS_NETWARE if (ret) printf("ERROR: %d\n", ret); # endif EXIT(ret); return (ret); }
int main(int count, char *strings[]) { SSL_CTX *ctx; int server; int choice=0; SSL *ssl; char buf[1024]; int bytes; char *hostname, *portnum; char filename[20] ; if ( count != 3 ){ printf("usage: %s <hostname> <portnum>\n", strings[0]); exit(0); } SSL_library_init(); hostname=strings[1]; portnum=strings[2]; ctx = InitCTX(); server = OpenConnection(hostname, atoi(portnum)); ssl = SSL_new(ctx); /* create new SSL connection state */ SSL_set_fd(ssl, server); /* attach the socket descriptor */ if ( SSL_connect(ssl) == FAIL ) /* perform the connection */ ERR_print_errors_fp(stderr); else{ printf("Connected with %s encryption\n\n", SSL_get_cipher(ssl)); ShowCerts(ssl); /* get any certs */ printf("\n\n"); printf("Welcome to Cloud Storage System :\n Enter 1 - FILE UPLOAD\n 2 - FILE DOWNLOAD \n "); scanf("%d",&choice); if(choice ==1){ printf("Enter the file name you want to upload :"); scanf(" %s",filename); FILE *fp = fopen(filename,"r"); if(fp==NULL){ printf("File open error\n\n"); SSL_free(ssl); close(server); /* close socket */ SSL_CTX_free(ctx); return 1; } SSL_write(ssl,filename,sizeof(filename)); char ack[10]; SSL_read(ssl,ack,sizeof(ack)); printf("File name ACK received: %s\n\n",ack); /* Read data from file and send it. First read file in chunks of BUF_SIZE bytes */ unsigned char buff[BUF_SIZE]={0}; int nread = fread(buff,1,BUF_SIZE,fp); printf("Bytes read %d \n", nread); /* If read was success, send data. */ if(nread > 0){ printf("Sending File contents to server Side \n"); SSL_write(ssl, buff, nread); /* send file contents to server */ calHmac(buff,filename,choice); } // SSL_write(ssl, msg, strlen(msg)); bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ buf[bytes] = 0; printf("\nReceived: File Created at Server \n" ); } else if(choice ==2){ printf("Enter the file name you want to download :"); scanf(" %s",filename); SSL_write(ssl,"DOWNLOAD",sizeof(filename)); char ack[30]; int replay=0; SSL_read(ssl,ack,sizeof(ack)); printf("File name ACK received: %s\n\n",ack); strcat(ack,"-"); strcat(ack,filename); printf("Do you want to try Replay Attack? If yes, enter 1:"); scanf("%d",&replay); if(replay ==1){ printf("Enter the data to replay :"); scanf("%s",ack); SSL_write(ssl,ack,sizeof(ack)); } else{ SSL_write(ssl,ack,sizeof(ack)); } unsigned char fileContent[256]; SSL_read(ssl,fileContent,sizeof(fileContent)); printf("File Contents received: %s\n\n",fileContent); calHmac(fileContent,filename,choice); //path where downloaded files are stored char filepath[90]="/Users/prashanth/Desktop/try-1/ProejectTry-2/Download/"; strcat(filepath,filename); FILE *DownloadFp=0; //writing Downloaded file contents to a new location DownloadFp = fopen(filepath, "w"); if(DownloadFp == NULL) printf("Sorry, file cannot be created\n"); else{ fwrite(fileContent,sizeof(unsigned char), sizeof(fileContent),DownloadFp); printf("\n Path of Downloaded file:%s \n",filepath); fclose(DownloadFp); } // Directory al } else{ printf("Invalid Choice\n"); exit(0); } SSL_free(ssl); /* release connection state */ } close(server); /* close socket */ SSL_CTX_free(ctx); /* release context */ return 0; }
int test_mod_mul(BIO *bp, BN_CTX *ctx) { BIGNUM *a,*b,*c,*d,*e; int i,j; a=BN_new(); b=BN_new(); c=BN_new(); d=BN_new(); e=BN_new(); for (j=0; j<3; j++) { BN_bntest_rand(c,1024,0,0); /**/ for (i=0; i<num0; i++) { BN_bntest_rand(a,475+i*10,0,0); /**/ BN_bntest_rand(b,425+i*11,0,0); /**/ a->neg=rand_neg(); b->neg=rand_neg(); if (!BN_mod_mul(e,a,b,c,ctx)) { unsigned long l; while ((l=ERR_get_error())) fprintf(stderr,"ERROR:%s\n", ERR_error_string(l,NULL)); EXIT(1); } if (bp != NULL) { if (!results) { BN_print(bp,a); BIO_puts(bp," * "); BN_print(bp,b); BIO_puts(bp," % "); BN_print(bp,c); if ((a->neg ^ b->neg) && !BN_is_zero(e)) { /* If (a*b) % c is negative, c must be added * in order to obtain the normalized remainder * (new with OpenSSL 0.9.7, previous versions of * BN_mod_mul could generate negative results) */ BIO_puts(bp," + "); BN_print(bp,c); } BIO_puts(bp," - "); } BN_print(bp,e); BIO_puts(bp,"\n"); } BN_mul(d,a,b,ctx); BN_sub(d,d,e); BN_div(a,b,d,c,ctx); if(!BN_is_zero(b)) { fprintf(stderr,"Modulo multiply test failed!\n"); ERR_print_errors_fp(stderr); return 0; } } } BN_free(a); BN_free(b); BN_free(c); BN_free(d); BN_free(e); return(1); }
static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id, const char *CAfile, const char *cert, const char *key, const char *dcert, const char *dkey, const char *cipher_list, const char *dh_file, const char *dh_special, int tmp_rsa, int ctx_options, int out_state, int out_verify, int verify_mode, unsigned int verify_depth) { SSL_CTX *ctx = NULL, *ret = NULL; const SSL_METHOD *meth; ENGINE *e = NULL; OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); meth = (server_mode ? SSLv23_server_method() : SSLv23_client_method()); if (meth == NULL) goto err; if (engine_id) { ENGINE_load_builtin_engines(); if ((e = ENGINE_by_id(engine_id)) == NULL) { fprintf(stderr, "Error obtaining '%s' engine, openssl " "errors follow\n", engine_id); goto err; } if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { fprintf(stderr, "Error assigning '%s' engine, openssl " "errors follow\n", engine_id); goto err; } ENGINE_free(e); } if ((ctx = SSL_CTX_new(meth)) == NULL) goto err; /* cacert */ if (CAfile) { if (!X509_STORE_load_locations(SSL_CTX_get_cert_store(ctx), CAfile, NULL)) { fprintf(stderr, "Error loading CA cert(s) in '%s'\n", CAfile); goto err; } fprintf(stderr, "Info, operating with CA cert(s) in '%s'\n", CAfile); } else fprintf(stderr, "Info, operating without a CA cert(-list)\n"); if (!SSL_CTX_set_default_verify_paths(ctx)) { fprintf(stderr, "Error setting default verify paths\n"); goto err; } /* cert and key */ if ((cert || key) && !ctx_set_cert(ctx, cert, key)) goto err; /* dcert and dkey */ if ((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey)) goto err; /* temporary RSA key generation */ if (tmp_rsa) SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa); /* cipher_list */ if (cipher_list) { if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) { fprintf(stderr, "Error setting cipher list '%s'\n", cipher_list); goto err; } fprintf(stderr, "Info, set cipher list '%s'\n", cipher_list); } else fprintf(stderr, "Info, operating with default cipher list\n"); /* dh_file & dh_special */ if ((dh_file || dh_special) && !ctx_set_dh(ctx, dh_file, dh_special)) goto err; /* ctx_options */ SSL_CTX_set_options(ctx, ctx_options); /* out_state (output of SSL handshake states to screen). */ if (out_state) cb_ssl_info_set_output(stderr); /* out_verify */ if (out_verify > 0) { cb_ssl_verify_set_output(stderr); cb_ssl_verify_set_level(out_verify); } /* verify_depth */ cb_ssl_verify_set_depth(verify_depth); /* Success! (includes setting verify_mode) */ SSL_CTX_set_info_callback(ctx, cb_ssl_info); SSL_CTX_set_verify(ctx, verify_mode, cb_ssl_verify); ret = ctx; err: if (!ret) { ERR_print_errors_fp(stderr); if (ctx) SSL_CTX_free(ctx); } return ret; }
int SFSocketConnectToHost (SFSocket *clientSocket, const char *host, int port) { struct sockaddr_in *addr = NULL; struct hostent *hp = NULL; SSL_CTX *ctx = NULL; int sock = 0; if ((hp = gethostbyname(host)) == NULL) return(-1); /* Setup Address */ addr = SFSocketAddress(clientSocket); memset(addr, 0, sizeof(struct sockaddr_in)); addr->sin_addr = *((struct in_addr *)hp->h_addr_list[0]); addr->sin_family = AF_INET; addr->sin_port = htons(port); #ifdef _WIN32 if ( INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) ) #else if (0 > (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) #endif return(-2); /* Connect to Host */ #ifdef _WIN32 if (SOCKET_ERROR == connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) ) #else if (0 > connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in))) #endif { #ifdef _WIN32 errno_t theError = WSAGetLastError(); closesocket(sock); #else close(sock); #endif sock = 0; return(-3); } /* Set Socket Descriptor */ SFSocketSetDescriptor(clientSocket, sock); if (NULL != (ctx = SFSocketContext(clientSocket))) { BIO *bio = NULL; SSL *ssl = NULL; /* Setup SSL */ if (NULL == (ssl = SSL_new(ctx))) { ERR_print_errors_fp(stderr); SFSocketClearDescriptor(clientSocket); #ifdef _WIN32 closesocket(sock); #else close(sock); #endif sock = 0; return(-4); } /* Setup BIO */ if ((bio = BIO_new_socket(sock, BIO_NOCLOSE)) == NULL) { SFSocketClearDescriptor(clientSocket); SSL_free(ssl); #ifdef _WIN32 closesocket(sock); #else close(sock); #endif sock = 0; return(-5); } /* SSL Connect */ SSL_set_bio(ssl, bio, bio); if (0 >= SSL_connect(ssl)) { ERR_print_errors_fp(stderr); return(-6); } /* Setup SSL/BIO on Socket */ SFSocketSetSSL(clientSocket, ssl); SFSocketSetBIO(clientSocket, bio); //TODO Figure out why Certs weren't working. // TODO get certs working. // TODO otherwise at least figure out how to call this without a cert /* Check Certificate */ // if (__SFSocketCheckCert(clientSocket, host) < 0) // return(-7); } return(0); }
/* handles a client connection */ void handle_connection(int sock){ u_int32_t calculated_crc32; command *temp_command; packet receive_packet; packet send_packet; int bytes_to_send; int bytes_to_recv; char buffer[MAX_INPUT_BUFFER]; char raw_command[MAX_INPUT_BUFFER]; char processed_command[MAX_INPUT_BUFFER]; int result=STATE_OK; int early_timeout=FALSE; int rc; int x; #ifdef DEBUG FILE *errfp; #endif #ifdef HAVE_SSL SSL *ssl=NULL; #endif /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Handling the connection..."); #ifdef OLDSTUFF /* socket should be non-blocking */ fcntl(sock,F_SETFL,O_NONBLOCK); #endif /* set connection handler */ signal(SIGALRM,my_connection_sighandler); alarm(connection_timeout); #ifdef HAVE_SSL /* do SSL handshake */ if(result==STATE_OK && use_ssl==TRUE){ if((ssl=SSL_new(ctx))!=NULL){ SSL_set_fd(ssl,sock); /* keep attempting the request if needed */ while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); if(rc!=1){ syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc)); #ifdef DEBUG errfp=fopen("/tmp/err.log","w"); ERR_print_errors_fp(errfp); fclose(errfp); #endif return; } } else{ syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n"); #ifdef DEBUG errfp=fopen("/tmp/err.log","w"); ERR_print_errors_fp(errfp); fclose(errfp); #endif return; } } #endif bytes_to_recv=sizeof(receive_packet); if(use_ssl==FALSE) rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout); #ifdef HAVE_SSL else{ while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); } #endif /* recv() error or client disconnect */ if(rc<=0){ /* log error to syslog facility */ syslog(LOG_ERR,"Could not read request from client, bailing out..."); #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n"); } #endif return; } /* we couldn't read the correct amount of data, so bail out */ else if(bytes_to_recv!=sizeof(receive_packet)){ /* log error to syslog facility */ syslog(LOG_ERR,"Data packet from client was too short, bailing out..."); #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif return; } #ifdef DEBUG fp=fopen("/tmp/packet","w"); if(fp){ fwrite(&receive_packet,1,sizeof(receive_packet),fp); fclose(fp); } #endif /* make sure the request is valid */ if(validate_request(&receive_packet)==ERROR){ /* log an error */ syslog(LOG_ERR,"Client request was invalid, bailing out..."); /* free memory */ free(command_name); command_name=NULL; for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ free(macro_argv[x]); macro_argv[x]=NULL; } #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif return; } /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer); /* disable connection alarm - a new alarm will be setup during my_system */ alarm(0); /* if this is the version check command, just spew it out */ if(!strcmp(command_name,NRPE_HELLO_COMMAND)){ snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION); buffer[sizeof(buffer)-1]='\x0'; /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Response: %s",buffer); result=STATE_OK; } /* find the command we're supposed to run */ else{ temp_command=find_command(command_name); if(temp_command==NULL){ snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name); buffer[sizeof(buffer)-1]='\x0'; /* log error to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"%s",buffer); result=STATE_CRITICAL; } else{ /* process command line */ if(command_prefix==NULL) strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1); else snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line); raw_command[sizeof(raw_command)-1]='\x0'; process_macros(raw_command,processed_command,sizeof(processed_command)); /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Running command: %s",processed_command); /* run the command */ strcpy(buffer,""); result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer)); /* log debug info */ if(debug==TRUE) syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer); /* see if the command timed out */ if(early_timeout==TRUE) snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout); else if(!strcmp(buffer,"")) snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n"); buffer[sizeof(buffer)-1]='\x0'; /* check return code bounds */ if((result<0) || (result>3)){ /* log error to syslog facility */ syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result); result=STATE_UNKNOWN; } } } /* free memory */ free(command_name); command_name=NULL; for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ free(macro_argv[x]); macro_argv[x]=NULL; } /* strip newline character from end of output buffer */ if(buffer[strlen(buffer)-1]=='\n') buffer[strlen(buffer)-1]='\x0'; /* clear the response packet buffer */ bzero(&send_packet,sizeof(send_packet)); /* fill the packet with semi-random data */ randomize_buffer((char *)&send_packet,sizeof(send_packet)); /* initialize response packet data */ send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET); send_packet.result_code=(int16_t)htons(result); strncpy(&send_packet.buffer[0],buffer,MAX_PACKETBUFFER_LENGTH); send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; /* calculate the crc 32 value of the packet */ send_packet.crc32_value=(u_int32_t)0L; calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet)); send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32); /***** ENCRYPT RESPONSE *****/ /* send the response back to the client */ bytes_to_send=sizeof(send_packet); if(use_ssl==FALSE) sendall(sock,(char *)&send_packet,&bytes_to_send); #ifdef HAVE_SSL else SSL_write(ssl,&send_packet,bytes_to_send); #endif #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer); return; }
int main(int argc, char *argv[]) { BN_GENCB *_cb = NULL; DH *a = NULL; DH *b = NULL; BIGNUM *ap = NULL, *ag = NULL, *bp = NULL, *bg = NULL, *apub_key = NULL; BIGNUM *bpub_key = NULL, *priv_key = NULL; char buf[12] = {0}; unsigned char *abuf = NULL; unsigned char *bbuf = NULL; int i, alen, blen, aout, bout; int ret = 1; BIO *out = NULL; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof rnd_seed); out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); _cb = BN_GENCB_new(); if (_cb == NULL) goto err; BN_GENCB_set(_cb, &cb, out); if (((a = DH_new()) == NULL) || (!DH_generate_parameters_ex(a, 64, DH_GENERATOR_5, _cb))) goto err; if (!DH_check(a, &i)) goto err; if (i & DH_CHECK_P_NOT_PRIME) BIO_puts(out, "p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) BIO_puts(out, "p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) BIO_puts(out, "unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) BIO_puts(out, "the g value is not a generator\n"); DH_get0_pqg(a, &ap, NULL, &ag); BIO_puts(out, "\np ="); BN_print(out, ap); BIO_puts(out, "\ng ="); BN_print(out, ag); BIO_puts(out, "\n"); b = DH_new(); if (b == NULL) goto err; bp = BN_dup(ap); bg = BN_dup(ag); if ((bp == NULL) || (bg == NULL) || !DH_set0_pqg(b, bp, NULL, bg)) goto err; bp = bg = NULL; if (!DH_generate_key(a)) goto err; DH_get0_key(a, &apub_key, &priv_key); BIO_puts(out, "pri 1="); BN_print(out, priv_key); BIO_puts(out, "\npub 1="); BN_print(out, apub_key); BIO_puts(out, "\n"); if (!DH_generate_key(b)) goto err; DH_get0_key(b, &bpub_key, &priv_key); BIO_puts(out, "pri 2="); BN_print(out, priv_key); BIO_puts(out, "\npub 2="); BN_print(out, bpub_key); BIO_puts(out, "\n"); alen = DH_size(a); abuf = OPENSSL_malloc(alen); if (abuf == NULL) goto err; aout = DH_compute_key(abuf, bpub_key, a); BIO_puts(out, "key1 ="); for (i = 0; i < aout; i++) { sprintf(buf, "%02X", abuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); blen = DH_size(b); bbuf = OPENSSL_malloc(blen); if (bbuf == NULL) goto err; bout = DH_compute_key(bbuf, apub_key, b); BIO_puts(out, "key2 ="); for (i = 0; i < bout; i++) { sprintf(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { fprintf(stderr, "Error in DH routines\n"); ret = 1; } else ret = 0; if (!run_rfc5114_tests()) ret = 1; err: (void)BIO_flush(out); ERR_print_errors_fp(stderr); OPENSSL_free(abuf); OPENSSL_free(bbuf); DH_free(b); DH_free(a); BN_free(bp); BN_free(bg); BN_GENCB_free(_cb); BIO_free(out); #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) ret = 1; #endif EXIT(ret); }
int main(int argc, char **argv) { int debug=0; int verify=0; int mismatch=0; char *program; int badops=0; char *certfile=NULL; char *out1file=NULL; char *out2file=NULL; char *home=NULL; char *pin=NULL; char *argp; char *ss; BIO *bio_err; X509 *ucert; FILE *fp; FILE *fpout; #ifdef USE_PKCS11 CK_SESSION_HANDLE hSession = 0; #endif #ifdef WIN32 CRYPTO_malloc_init(); #endif ERR_load_prxyerr_strings(0); SSLeay_add_ssl_algorithms(); if ((bio_err=BIO_new(BIO_s_file())) != NULL) { BIO_set_fp(bio_err,stderr,BIO_NOCLOSE); } program=argv[0]; argc--; argv++; while (argc >= 1) { argp = *argv; if ( *argp == '-' && *(argp+1) == '-') { argp++; } if (strcmp(argp,"-debug") == 0) { debug++; } else if (strcmp(argp,"-cert") == 0) { if (--argc < 1) goto bad; certfile=*(++argv); } else if (strcmp(argp,"-out1") == 0) { if (--argc < 1) goto bad; out1file=*(++argv); } else if (strcmp(argp,"-out2") == 0) { if (--argc < 1) goto bad; out2file=*(++argv); } else if (strcmp(argp,"-help") == 0) { badops=1; break; } else { fprintf(stderr,_GGSL("unknown option %s\n"),*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: fprintf(stderr,_GGSL("%s [options]\n"),program); fprintf(stderr,_GGSL("where options are\n")); fprintf(stderr,_GGSL(" --help show this list\n")); fprintf(stderr,_GGSL(" --debug set debugging on\n")); fprintf(stderr,_GGSL(" --cert file name of long term certificate\n")); fprintf(stderr,_GGSL(" --out1 file name for name\n")); fprintf(stderr,_GGSL(" --out2 file name for commonName\n"); exit(1); } home = (char *)getenv("HOME"); if (home == NULL) { #ifndef WIN32 fprintf(stderr,_GGSL("$HOME not defined")); exit(1); #else home = "c:\\windows"; #endif } if (!strncmp(certfile,"SC:",3)) { #ifdef USE_PKCS11 char *cp; char *kp; int rc; cp = certfile + 3; kp = strchr(cp,':'); if (kp == NULL) { fprintf(stderr,_GGSL("Bad format of cert name, SC:card:cert\n")); exit (2); } kp++; /* skip the : */ if (hSession == 0) { rc = sc_init(&hSession, cp, NULL, pin, CKU_USER, 0); if (rc) { fprintf(stderr,_GGSL("Failed to open card session\n")); ERR_print_errors_fp (stderr); exit(2); } } rc = sc_get_cert_obj_by_label(hSession,kp,&ucert); if (rc) { fprintf(stderr,_GGSL("Failed to find certificate on card \n")); ERR_print_errors_fp (stderr); exit(2); } #else fprintf(stderr,_GGSL("Smart card support not compiled with this program\n")); exit (2); #endif /* USE_PKCS11 */ } else { fp = fopen (certfile, "r"); if (fp == NULL) { fprintf(stderr,_GGSL(" failed to open %s\n",certfile)); exit (1); } ucert = PEM_read_X509 (fp, NULL, OPENSSL_PEM_CB(NULL, NULL)); fclose (fp); } if (ucert == NULL) { ERR_print_errors_fp (stderr); exit (1); } if (out1file) { if (strcmp("-",out1file)) { fpout=fopen(out1file,"w"); } else { fpout = stdout; } if (fpout == NULL) { fprintf (stderr,"Unable to open out1 file:%s\n", out1file); exit(4); } ss = X509_NAME_oneline(ucert->cert_info->subject,NULL,0); while (1) { if (!strcmp(ss+strlen(ss)-strlen("/CN=limited proxy"), "/CN=limited proxy")) { *(ss+strlen(ss)-strlen("/CN=limited proxy"))= '\0'; } else if (!strcmp(ss+strlen(ss)-strlen("/CN=proxy"), "/CN=proxy")) { *(ss+strlen(ss)-strlen("/CN=proxy")) = '\0'; } else { break; } } fprintf(fpout,"%s\n",ss); OPENSSL_free(ss); if (fpout != stdout) { fclose(fpout); } } if (out2file) { if (strcmp("-",out2file)) { fpout=fopen(out2file,"w"); } else { fpout = stdout; } if (fpout == NULL) { fprintf (stderr,"Unable to open out2 file:%s\n", out2file); exit(4); } { X509_NAME *subject; X509_NAME_ENTRY *ne; ASN1_STRING *data; X509_NAME_ENTRY *o = NULL; X509_NAME_ENTRY *ou1 = NULL; X509_NAME_ENTRY *ou2 = NULL; int i; subject=X509_get_subject_name(ucert); i = X509_NAME_entry_count(subject)-1; while (i > 0) { ne=X509_NAME_get_entry(subject,i); if (!OBJ_cmp(ne->object, OBJ_nid2obj(NID_organizationName))) { if (!o) { o = ne; } } if (!OBJ_cmp(ne->object, OBJ_nid2obj(NID_organizationalUnitName))) { if (ou2) { ou1 = ne; } else { ou2 = ne; } } if (!OBJ_cmp(ne->object, OBJ_nid2obj(NID_commonName))) { data=X509_NAME_ENTRY_get_data(ne); if ((data->length == 5 && !memcmp(data->data,"proxy",5)) || (data->length == 13 && !memcmp(data->data,"limited proxy",13))) { i--; continue; } fprintf(fpout,"%.*s\n",data->length,data->data); /* break; */ } i--; } if (o) { data=X509_NAME_ENTRY_get_data(o); fprintf(fpout,"%.*s\n",data->length,data->data); } if (ou1) { data=X509_NAME_ENTRY_get_data(ou1); fprintf(fpout,"%.*s\n",data->length,data->data); } if (ou2) { data=X509_NAME_ENTRY_get_data(ou2); fprintf(fpout,"%.*s\n",data->length,data->data); } } /* inline section */ if (fpout != stdout) { fclose(fpout); } } /* out2file */ return 0; }