int main(int argc, char **argv) { int optc, quiet = 0; static const struct option options[] = { { "quiet", no_argument, NULL, 'q' }, { "period", required_argument, NULL, 'p' }, { "address", required_argument, NULL, 'a' }, { NULL } }; /* The 'timezone' global is needed to adjust local times from * mktime() back to UTC: */ tzset(); while ((optc = getopt_long(argc, argv, "qhvp:", options, NULL)) != -1) { switch (optc) { case 'q': quiet = 1; break; case 'p': warn_period = atoi(optarg); break; case 'a': warn_address = strdup(optarg); break; default: exit(2); } } return check_cert(argv[optind], quiet) == 1 ? EXIT_SUCCESS : EXIT_FAILURE; }
// Perform a connect void doConnect (char *proto, int slices_len, int N_proxies, SPP_SLICE **slice_set, SPP_PROXY **proxies){ // SPP CONNECT if (strcmp(proto, "spp") == 0){ #ifdef DEBUG printf("[DEBUG] SPP_connect\n"); #endif if (SPP_connect(ssl, slice_set, slices_len, proxies, N_proxies) <= 0){ berr_exit("SPP connect error"); } } // SSL CONNECT if (strcmp(proto, "ssl") == 0){ #ifdef DEBUG printf("[DEBUG] SSL_connect\n"); #endif if(SSL_connect(ssl) <= 0) berr_exit("SSL connect error"); } // TO DO -- Check here if(require_server_auth){ #ifdef DEBUG printf("[DEBUG] Check certificate\n"); #endif check_cert(host); } }
static int pv_check_cert(sip_msg_t* msg, pv_param_t* param, pv_value_t* res) { int err; switch (param->pvn.u.isname.name.n) { case PV_CERT_VERIFIED: err = X509_V_OK; break; case PV_CERT_REVOKED: err = X509_V_ERR_CERT_REVOKED; break; case PV_CERT_EXPIRED: err = X509_V_ERR_CERT_HAS_EXPIRED; break; case PV_CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break; default: BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n); return pv_get_null(msg, param, res); } if (check_cert(&res->rs, &res->ri, 0, err, msg) < 0) { return pv_get_null(msg, param, res); } res->flags = PV_VAL_STR | PV_VAL_INT; return 0; }
/* * Get SSL/TLS certificate check it, maybe ask user about it and act * accordingly. */ int get_cert(session *ssn) { X509 *cert; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; long verify; mdlen = 0; if (!(cert = SSL_get_peer_certificate(ssn->sslconn))) return -1; verify = SSL_get_verify_result(ssn->sslconn); if (!((verify == X509_V_OK) || (verify == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) || (verify == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY))) { error("certificate verification failed; %d\n", verify); goto fail; } if (verify != X509_V_OK) { if (!(X509_digest(cert, EVP_md5(), md, &mdlen))) return -1; switch (check_cert(cert, md, &mdlen)) { case 0: if (isatty(STDIN_FILENO) == 0) fatal(ERROR_CERTIFICATE, "%s\n", "can't accept certificate in " "non-interactive mode"); print_cert(cert, md, &mdlen); if (store_cert(cert) == -1) goto fail; break; case -1: error("certificate mismatch occured\n"); goto fail; } } X509_free(cert); return 0; fail: X509_free(cert); return -1; }
/* * Get SSL/TLS certificate check it, maybe ask user about it and act * accordingly. */ int get_cert(session *ssn) { X509 *cert; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; mdlen = 0; if (!(cert = SSL_get_peer_certificate(ssn->sslconn))) return -1; if (!(X509_digest(cert, EVP_md5(), md, &mdlen))) return -1; switch (check_cert(cert, md, &mdlen)) { case 0: if (isatty(STDIN_FILENO) == 0) fatal(ERROR_CERTIFICATE, "%s\n", "can't accept certificate in non-interactive mode"); print_cert(cert, md, &mdlen); if (write_cert(cert) == -1) goto fail; break; case -1: if (isatty(STDIN_FILENO) == 0) fatal(ERROR_CERTIFICATE, "%s\n", "certificate mismatch in non-interactive mode"); print_cert(cert, md, &mdlen); if (mismatch_cert() == -1) goto fail; break; } X509_free(cert); return 0; fail: X509_free(cert); return -1; }
static int sel_check_cert(str* res, select_t* s, sip_msg_t* msg) { int local, err; switch(s->params[s->n - 2].v.i) { case CERT_PEER: local = 0; break; case CERT_LOCAL: local = 1; break; default: BUG("Bug in call to sel_cert_version\n"); return -1; } switch (s->params[s->n - 1].v.i) { case CERT_VERIFIED: err = X509_V_OK; break; case CERT_REVOKED: err = X509_V_ERR_CERT_REVOKED; break; case CERT_EXPIRED: err = X509_V_ERR_CERT_HAS_EXPIRED; break; case CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break; default: BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i); return -1; } return check_cert(res, NULL, local, err, msg); }
int main(int argc, char** argv) { if(argc<4) { printf("Usage: ./wserver cert-file priv-key-file pub-key-file.\n"); exit(0); } else { CERTFILE = argv[1]; KEYFILE = argv[2]; PUBFILE = argv[3]; const char* PROMPT = "Enter password for Old Key file: "; if(argc == 5) { OLDKEY = argv[4]; PASSWORD = getpass(PROMPT); OLDPASS = (char*) calloc(1, strlen(PASSWORD)+1); strcpy(OLDPASS, PASSWORD); } PROMPT = "Enter password for Key file: "; PASSWORD = getpass(PROMPT); } int sock,s; BIO *sbio; SSL_CTX *ctx; SSL *ssl; int r; pid_t pid; char buf[BUFSIZZ]; char *owner = (char*) calloc(1,256); ctx=initialize_ctx(CERTFILE,KEYFILE,PASSWORD); load_dh_params(ctx,DHFILE); sock=tcp_listen(); if((s=accept(sock,0,0))<0) err_exit("Problem accepting"); sbio=BIO_new_socket(s,BIO_NOCLOSE); ssl=SSL_new(ctx); SSL_set_bio(ssl,sbio,sbio); SSL_set_verify(ssl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0); if((r=SSL_accept(ssl)<=0)) berr_exit("SSL accept error"); if(check_cert(ssl, ctx, &owner)<=0) { send_data(ssl, "Revoked"); printf("Connection Closed.\n"); close_SSL(ssl, sock); destroy_ctx(ctx); exit(0); } send_data(ssl, "Approved"); printf("User connected: %s\n", owner); if((pid=fork())){ close(s); } else { if(argc == 5) {recrypt();} while(1){ memset((void*)buf, 0, BUFSIZZ); if(rec_data(buf, ssl)>0) { printf("Command received: %s\n", buf); if(starts_with(buf, "PUT")){ put_file(ssl, buf, owner); } else if(starts_with(buf, "GET")){ get_file(ssl, buf, owner); } else if(starts_with(buf, "DELEGATE")){ delegate(ssl, buf, owner); } else if(starts_with(buf, "END")){ close_SSL(ssl, sock); break; } else { printf("Command not recognized\n"); } } else{ perror("Error receiving command\n"); break; } } } destroy_ctx(ctx); exit(0); }
/* * Name: addcert * Desc: Imports a user certificate into the keystore, along with a * private key. * Returns: 0 on success, non-zero otherwise. */ int addcert(int argc, char **argv) { int i; char keystore_file[MAXPATHLEN] = ""; char *keystore_base = NULL; char *homedir; char *passarg = NULL; char *import_passarg = NULL; char *altroot = NULL; char *prog = NULL; char *alias = NULL; char *infile = NULL; char *inkeyfile = NULL; keystore_encoding_format_t informat = NULL; char *informat_str = NULL; int ret = 1; boolean_t trusted = B_FALSE; boolean_t implicit_trust = B_FALSE; FILE *certfile = NULL; FILE *keyfile = NULL; X509 *cert = NULL; STACK_OF(X509) *trustcerts = NULL; EVP_PKEY *key = NULL; PKG_ERR *err = NULL; keystore_handle_t keystore = NULL; while ((i = getopt(argc, argv, ":a:k:e:f:n:P:p:R:ty")) != EOF) { switch (i) { case 'a': prog = optarg; break; case 'k': keystore_base = optarg; break; case 'e': inkeyfile = optarg; break; case 'f': informat_str = optarg; break; case 'n': alias = optarg; break; case 'P': passarg = optarg; break; case 'p': import_passarg = optarg; break; case 'R': altroot = optarg; break; case 't': trusted = B_TRUE; break; case 'y': implicit_trust = B_TRUE; break; case ':': log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt); /* LINTED fallthrough intentional */ case '?': default: log_msg(LOG_MSG_ERR, MSG_USAGE); goto cleanup; } } if (!trusted && alias == NULL) { /* for untrusted (user) certs, we require a name */ log_msg(LOG_MSG_ERR, MSG_USER_NAME); log_msg(LOG_MSG_ERR, MSG_USAGE); goto cleanup; } else if (trusted && alias != NULL) { /* for trusted certs, we cannot have a name */ log_msg(LOG_MSG_ERR, MSG_TRUSTED_NAME); log_msg(LOG_MSG_ERR, MSG_USAGE); goto cleanup; } if (trusted && inkeyfile != NULL) { /* for trusted certs, we cannot have a private key */ log_msg(LOG_MSG_ERR, MSG_TRUSTED_KEY); log_msg(LOG_MSG_ERR, MSG_USAGE); goto cleanup; } /* last argument should be the path to the certificate */ if ((argc-optind) > 1) { log_msg(LOG_MSG_ERR, MSG_USAGE); goto cleanup; } else if ((argc-optind) < 1) { infile = "stdin"; certfile = stdin; log_msg(LOG_MSG_DEBUG, "Loading stdin certificate"); } else { infile = argv[optind]; log_msg(LOG_MSG_DEBUG, "Loading <%s> certificate", argv[optind]); if ((certfile = fopen(infile, "r")) == NULL) { log_msg(LOG_MSG_ERR, MSG_OPEN, infile); goto cleanup; } } /* * if specific key file supplied, open it, otherwise open * default (stdin) */ if (inkeyfile != NULL) { if ((keyfile = fopen(inkeyfile, "r")) == NULL) { log_msg(LOG_MSG_ERR, MSG_OPEN, inkeyfile); goto cleanup; } } else { inkeyfile = "stdin"; keyfile = stdin; } /* set up proper keystore */ if (altroot != NULL) { if (strlcpy(keystore_file, altroot, MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot); goto cleanup; } if (strlcat(keystore_file, "/", MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot); goto cleanup; } } if (keystore_base == NULL) { if (geteuid() == 0 || altroot != NULL) { /* * If we have an alternate * root, then we have no choice but to use * root's keystore on that alternate root, * since there is no way to resolve a * user's home dir given an alternate root */ if (strlcat(keystore_file, PKGSEC, MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, keystore_file); goto cleanup; } } else { if ((homedir = getenv("HOME")) == NULL) { /* * not superuser, but no home dir, so * use superuser's keystore */ if (strlcat(keystore_file, PKGSEC, MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, keystore_file); goto cleanup; } } else { if (strlcat(keystore_file, homedir, MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, homedir); goto cleanup; } if (strlcat(keystore_file, "/.pkg/security", MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, keystore_file); goto cleanup; } } } } else { if (strlcat(keystore_file, keystore_base, MAXPATHLEN) >= MAXPATHLEN) { log_msg(LOG_MSG_ERR, MSG_TOO_LONG, keystore_base); goto cleanup; } } /* figure out input format */ if (informat_str == NULL) { informat = KEYSTORE_FORMAT_PEM; } else { if (ci_streq(informat_str, "pem")) { informat = KEYSTORE_FORMAT_PEM; } else if (ci_streq(informat_str, "der")) { informat = KEYSTORE_FORMAT_DER; } else { log_msg(LOG_MSG_ERR, MSG_BAD_FORMAT, informat_str); goto cleanup; } } err = pkgerr_new(); if (trusted) { /* load all possible certs */ if (load_all_certs(err, certfile, informat, import_passarg, &trustcerts) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } /* we must have gotten at least one cert, if not, fail */ if (sk_X509_num(trustcerts) < 1) { log_msg(LOG_MSG_ERR, MSG_NO_CERTS, infile); goto cleanup; } } else { /* first, try to load user certificate and key */ if (load_cert_and_key(err, certfile, informat, import_passarg, &key, &cert) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } /* we must have gotten a cert, if not, fail */ if (cert == NULL) { log_msg(LOG_MSG_ERR, MSG_NO_CERTS, infile); goto cleanup; } if (key == NULL) { /* * if we are importing a user cert, and did not get * a key, try to load it from the key file */ if (keyfile == NULL) { log_msg(LOG_MSG_ERR, MSG_NEED_KEY, infile); goto cleanup; } else { log_msg(LOG_MSG_DEBUG, "Loading private key <%s>", inkeyfile); if (load_cert_and_key(err, keyfile, informat, import_passarg, &key, NULL) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDKEY, inkeyfile); goto cleanup; } if (key == NULL) { log_msg(LOG_MSG_ERR, MSG_NO_PRIVKEY, inkeyfile); log_msg(LOG_MSG_ERR, MSG_NO_ADDKEY, inkeyfile); goto cleanup; } } } } if (trusted) { /* check validity date of all certificates */ for (i = 0; i < sk_X509_num(trustcerts); i++) { /* LINTED pointer cast may result in improper algnmnt */ cert = sk_X509_value(trustcerts, i); if (check_cert(err, cert) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } } } else { /* check validity date of user certificate */ if (check_cert_and_key(err, cert, key) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } } if (trusted && !implicit_trust) { /* * if importing more than one cert, must use implicit trust, * because we can't ask the user to individually trust * each one, since there may be many */ if (sk_X509_num(trustcerts) != 1) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_MULTIPLE_TRUST, infile, "-y"); goto cleanup; } else { /* LINTED pointer cast may result in improper algnmnt */ cert = sk_X509_value(trustcerts, 0); } /* ask the user */ switch (verify_trust(cert)) { case Accept: /* user accepted */ break; case Reject: /* user aborted operation */ log_msg(LOG_MSG_ERR, MSG_ADDCERT_ABORT); goto cleanup; case VerifyFailed: default: log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } } /* now load the key store */ log_msg(LOG_MSG_DEBUG, "Loading keystore <%s>", keystore_file); set_passphrase_prompt(MSG_KEYSTORE_PASSPROMPT); set_passphrase_passarg(passarg); if (open_keystore(err, keystore_file, prog, pkg_passphrase_cb, KEYSTORE_ACCESS_READWRITE | KEYSTORE_PATH_HARD, &keystore) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } /* now merge the new cert into the keystore */ log_msg(LOG_MSG_DEBUG, "Merging certificate <%s>", get_subject_display_name(cert)); if (trusted) { /* merge all trusted certs found */ for (i = 0; i < sk_X509_num(trustcerts); i++) { /* LINTED pointer cast may result in improper algnmnt */ cert = sk_X509_value(trustcerts, i); if (merge_ca_cert(err, cert, keystore) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } else { log_msg(LOG_MSG_INFO, MSG_TRUSTING, get_subject_display_name(cert)); } } } else { /* merge user cert */ if (merge_cert_and_key(err, cert, key, alias, keystore) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } } /* now write it back out */ log_msg(LOG_MSG_DEBUG, "Closing keystore"); set_passphrase_prompt(MSG_KEYSTORE_PASSOUTPROMPT); set_passphrase_passarg(passarg); if (close_keystore(err, keystore, pkg_passphrase_cb) != 0) { log_pkgerr(LOG_MSG_ERR, err); log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile); goto cleanup; } if (trusted) { log_msg(LOG_MSG_INFO, MSG_TRUSTED, infile); } else { log_msg(LOG_MSG_INFO, MSG_ADDED, infile, alias); } ret = 0; /* fallthrough intentional */ cleanup: if (err != NULL) pkgerr_free(err); if (certfile != NULL) (void) fclose(certfile); if (keyfile != NULL) (void) fclose(keyfile); return (ret); }
int main(int argc, char **argv) { int len, sock, port=PORT, r; SSL_CTX *ctx; SSL *ssl; BIO *sbio; char *ciphers = "SHA1"; char *host=HOST; char buf[256]; char *secret = "What's the question?"; /*Parse command line arguments*/ switch(argc){ case 1: break; case 3: host = argv[1]; port=atoi(argv[2]); if (port<1||port>65535){ fprintf(stderr,"invalid port number"); exit(0); } break; default: printf("Usage: %s server port\n", argv[0]); exit(0); } /* Build our SSL context*/ ctx=initialize_ctx(KEYFILE, PASSWORD); /* Set our cipher list */ if(ciphers){ SSL_CTX_set_cipher_list(ctx, ciphers); } SSL_CTX_set_session_id_context(ctx, (void*)&s_server_session_id_context, sizeof s_server_session_id_context); /* Connect the TCP socket*/ sock=tcp_connect(host,port); /* Connect the SSL socket */ ssl=SSL_new(ctx); sbio=BIO_new_socket(sock,BIO_NOCLOSE); SSL_set_bio(ssl,sbio,sbio); if(SSL_connect(ssl)<=0) { berr_exit(FMT_CONNECT_ERR); } check_cert(ssl, "Bob's Server"); r = SSL_write(ssl, secret, strlen(secret)); switch(SSL_get_error(ssl,r)){ /* We wrote something*/ case SSL_ERROR_NONE: break; case SSL_ERROR_WANT_WRITE: break; case SSL_ERROR_WANT_READ: break; /* Some other error */ default: berr_exit(FMT_INCORRECT_CLOSE); } r=SSL_read(ssl, &buf, 255); switch(SSL_get_error(ssl,r)){ case SSL_ERROR_NONE: len = r; break; case SSL_ERROR_ZERO_RETURN: /* End of data */ berr_exit(FMT_INCORRECT_CLOSE); break; case SSL_ERROR_WANT_READ: break; case SSL_ERROR_WANT_WRITE: break; default: berr_exit(FMT_INCORRECT_CLOSE); } buf[len]='\0'; /* this is how you output something for the marker to pick up */ printf(FMT_OUTPUT, secret, buf); if(SSL_shutdown(ssl) < 0) { berr_exit(FMT_INCORRECT_CLOSE); } SSL_free(ssl); close(sock); destroy_ctx(ctx); return 0; }
struct dyString *bio(char *host, char *url, char *certFile, char *certPath) /* This SSL/TLS client example, attempts to retrieve a page from an SSL/TLS web server. The I/O routines are identical to those of the unencrypted example in BIO_s_connect(3). */ { struct dyString *dy = dyStringNew(0); char hostnameProto[256]; char requestLine[4096]; BIO *sbio; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; SSL_library_init(); ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); /* We would seed the PRNG here if the platform didn't * do it automatically */ ctx = SSL_CTX_new(SSLv23_client_method()); if (certFile || certPath) { SSL_CTX_load_verify_locations(ctx,certFile,certPath); #if (OPENSSL_VERSION_NUMBER < 0x0090600fL) SSL_CTX_set_verify_depth(ctx,1); #endif } /* 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"); return NULL; } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ safef(hostnameProto,sizeof(hostnameProto),"%s:https",host); BIO_set_conn_hostname(sbio, hostnameProto); if(BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); return NULL; } if(BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); return NULL; } if (certFile || certPath) if (!check_cert(ssl, host)) return NULL; /* Could examine ssl here to get connection info */ safef(requestLine,sizeof(requestLine),"GET %s HTTP/1.0\n\n",url); BIO_puts(sbio, requestLine); for(;;) { len = BIO_read(sbio, tmpbuf, 1024); if(len <= 0) break; dyStringAppendN(dy, tmpbuf, len); } BIO_free_all(sbio); return dy; }
/* caller == ssl client, !client == ssl server */ int ssl_init(int caller, int fd, int iscontrol) { const SSL_METHOD *method; int ret; SSL_CTX **curctx; SSL **curssl; if (!_use_ssl) return 0; SSL_library_init (); SSL_load_error_strings (); if (iscontrol) { curctx = &control_ctx; curssl = &control_ssl; } else { curctx = &ctx; curssl = &ssl; } #if 0 if (caller) // method = SSLv23_client_method(); method = TLSv1_1_client_method(); else //method = SSLv23_method(); method = TLSv1_1_server_method(); #endif method = SSLv23_method(); *curctx = SSL_CTX_new (method); if (*curctx == NULL) { ERR_print_errors_fp(stderr); return -1; } /* Load cert */ if(!(SSL_CTX_use_certificate_file(*curctx, certfile, SSL_FILETYPE_PEM))) { ERR_print_errors_fp(stderr); return -1; } /* Load private key */ if(!(SSL_CTX_use_PrivateKey_file(*curctx, keyfile, SSL_FILETYPE_PEM))) { ERR_print_errors_fp(stderr); return -1; } /* Load the CAs we trust*/ if(!(SSL_CTX_load_verify_locations(*curctx, cafile, 0))) { ERR_print_errors_fp(stderr); return -1; } /* if in server role request peer's cert */ //if (!caller) SSL_CTX_set_verify(*curctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, 0); SSL_CTX_set_verify_depth(*curctx, 1); STACK_OF(X509_NAME) *cert_names; cert_names = SSL_load_client_CA_file(cafile); if (cert_names != NULL) { printf("loaded client ca list\n"); SSL_CTX_set_client_CA_list(*curctx, cert_names); } else printf("not loaded client ca list\n"); SSL_CTX_set_mode(*curctx, SSL_MODE_AUTO_RETRY); *curssl = SSL_new(*curctx); if (*curssl == NULL) { ERR_print_errors_fp(stderr); return -1; } if (!SSL_set_fd (*curssl, fd)) { ERR_print_errors_fp(stderr); return -1; } if (caller) { if (SSL_connect (*curssl) != 1) { ERR_print_errors_fp(stderr); printf("ssl error %d\n", SSL_get_error(*curssl, ret)); return -1; } } else { if((ret = SSL_accept(*curssl)) <=0 ) { ERR_print_errors_fp(stderr); printf("ssl error %d\n", SSL_get_error(*curssl, ret)); return -1; } } return check_cert(*curssl); }