| #include "cwmp/http.h" | |
| #include "cwmp/log.h" | |
| //#include "cwmp_private.h" | |
| #include <cwmp/md5.h> | |
| #ifdef USE_CWMP_OPENSSL | |
| static char openssl_password[32]; | |
| BIO *bio_err=0; | |
| static char *pass; | |
| static int password_cb(char *buf,int num, | |
| int rwflag,void *userdata); | |
| static void sigpipe_handle(int x); | |
| /* A simple error and exit routine*/ | |
| int err_exit(string) | |
| char *string; | |
| { | |
| cwmp_log_error("%s\n",string); | |
| //exit(0); | |
| } | |
| /* Print SSL errors and exit*/ | |
| int berr_exit(string) | |
| char *string; | |
| { | |
| cwmp_log_error("%s\n",string); | |
| ERR_print_errors(bio_err); | |
| //exit(0); | |
| } | |
| /*The password code is not thread safe*/ | |
| static int password_cb(char *buf,int num, | |
| int rwflag,void *userdata) | |
| { | |
| if(num<strlen(pass)+1) | |
| return(0); | |
| strcpy(buf,pass); | |
| return(strlen(pass)); | |
| } | |
| static void sigpipe_handle(int x){ | |
| } | |
| SSL_CTX *openssl_initialize_ctx(char *keyfile,char *password) | |
| { | |
| SSL_METHOD *meth; | |
| SSL_CTX *ctx; | |
| if(!bio_err){ | |
| /* Global system initialization*/ | |
| SSL_library_init(); | |
| SSL_load_error_strings(); | |
| /* An error write context */ | |
| bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); | |
| } | |
| /* Set up a SIGPIPE handler */ | |
| //signal(SIGPIPE,sigpipe_handle); | |
| /* Create our context*/ | |
| meth=SSLv23_method(); | |
| ctx=SSL_CTX_new(meth); | |
| /* Load our keys and certificates*/ | |
| if(!(SSL_CTX_use_certificate_chain_file(ctx, | |
| keyfile))) | |
| berr_exit("Can't read certificate file"); | |
| pass=password; | |
| SSL_CTX_set_default_passwd_cb(ctx, | |
| password_cb); | |
| if(!(SSL_CTX_use_PrivateKey_file(ctx, | |
| keyfile,SSL_FILETYPE_PEM))) | |
| berr_exit("Can't read key file"); | |
| /* Load the CAs we trust*/ | |
| /* | |
| if(!(SSL_CTX_load_verify_locations(ctx, | |
| CA_LIST,0))) | |
| berr_exit("Can't read CA list"); | |
| */ | |
| #if (OPENSSL_VERSION_NUMBER < 0x00905100L) | |
| SSL_CTX_set_verify_depth(ctx,1); | |
| #endif | |
| return ctx; | |
| } | |
| void openssl_destroy_ctx(ctx) | |
| SSL_CTX *ctx; | |
| { | |
| SSL_CTX_free(ctx); | |
| } | |
| SSL * openssl_connect(SSL_CTX * ctx, int fd) | |
| { | |
| BIO *sbio; | |
| SSL * ssl=SSL_new(ctx); | |
| sbio=BIO_new_socket(fd,BIO_NOCLOSE); | |
| SSL_set_bio(ssl,sbio,sbio); | |
| if(SSL_connect(ssl)<=0) | |
| { | |
| cwmp_log_alert("SSL connect error"); | |
| SSL_free(ssl); | |
| return NULL; | |
| } | |
| else | |
| { | |
| cwmp_log_info("SSL connect to host ok.\n"); | |
| } | |
| return ssl; | |
| } | |
| /* | |
| static int openssl_password_cb(char *buf, int num, int rwflag, void *userdata) | |
| { | |
| if (num < strlen(openssl_password)+1) | |
| return 0; | |
| strcpy(buf,openssl_password); | |
| return(strlen(buf)); | |
| } | |
| void openssl_init(void) { | |
| } | |
| int openssl_verify_callback(int ok, X509_STORE_CTX *store) { | |
| char data[256]; | |
| if (!ok) { | |
| X509 *cert = X509_STORE_CTX_get_current_cert(store); | |
| int depth = X509_STORE_CTX_get_error_depth(store); | |
| int err = X509_STORE_CTX_get_error(store); | |
| cwmp_log_error("Error with certificate at depth: %i\n", depth); | |
| X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); | |
| cwmp_log_error("issuer = %s\n", data); | |
| X509_NAME_oneline(X509_get_subject_name(cert), data, 256); | |
| cwmp_log_error("subject = %s\n", data); | |
| cwmp_log_error("err %i:%s\n", err, X509_verify_cert_error_string(err)); | |
| } | |
| return ok; | |
| } | |
| */ | |
| //SSL_CTX *openssl_setup_client_ctx(const char * cafile, const char * password) | |
| //{ | |
| // SSL_CTX *ctx; | |
| // | |
| // if (!SSL_library_init()) { | |
| // fprintf(stderr, "OpenSSL initialization failed!\n"); | |
| // cwmp_log_error("OpenSSL initialization failed!\n"); | |
| // exit(-1); | |
| // } | |
| // SSL_load_error_strings(); | |
| // | |
| // ctx = SSL_CTX_new(SSLv3_client_method()); | |
| // | |
| // /* Load our keys and certificates*/ | |
| // if(!(SSL_CTX_use_certificate_chain_file(ctx, cafile))) | |
| // { | |
| // cwmp_log_error("Can't read certificate file"); | |
| // | |
| // //return NULL; | |
| // } | |
| // | |
| // strncpy(openssl_password, password, 32); | |
| // | |
| // SSL_CTX_set_default_passwd_cb(ctx, openssl_password_cb); | |
| // if(!(SSL_CTX_use_PrivateKey_file(ctx, | |
| // cafile,SSL_FILETYPE_PEM))) | |
| // { | |
| // cwmp_log_error("Can't read key file"); | |
| // //return NULL | |
| // } | |
| // | |
| // /* Load the CAs we trust*/ | |
| // /*if(!(SSL_CTX_load_verify_locations(ctx, CA_LIST,0))) | |
| // { | |
| // cwmp_log_error("Can't read CA list"); | |
| // //return NULL | |
| // } | |
| // */ | |
| // SSL_CTX_set_verify_depth(ctx,4); | |
| // SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2); | |
| // | |
| // | |
| ///* | |
| // | |
| // if (SSL_CTX_load_verify_locations(ctx, cafile, cadir) != 1) | |
| // cwmp_log_error("Error loading CA file and/or directory"); | |
| // if (SSL_CTX_set_default_verify_paths(ctx) != 1) | |
| // cwmp_log_error("Error loading default CA file and/or directory"); | |
| // | |
| // SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, openssl_verify_callback); | |
| // SSL_CTX_set_verify_depth(ctx, 4); | |
| // SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2); | |
| // if (SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) != 1) | |
| // cwmp_log_error("Error setting cipher list (no valid ciphers)"); | |
| // | |
| //*/ | |
| // cwmp_log_debug("init openssl success.\n"); | |
| // return ctx; | |
| //} | |
| int openssl_check_cert(SSL *ssl, char *host) | |
| { | |
| X509 *peer; | |
| char peer_CN[256]; | |
| if(SSL_get_verify_result(ssl)!=X509_V_OK) | |
| { | |
| cwmp_log_error("Certificate doesn't verify"); | |
| //return CWMP_ERROR; | |
| } | |
| /*Check the cert chain. The chain length | |
| is automatically checked by OpenSSL when | |
| we set the verify depth in the ctx */ | |
| /*Check the common name*/ | |
| peer=SSL_get_peer_certificate(ssl); | |
| X509_NAME_get_text_by_NID | |
| (X509_get_subject_name(peer), | |
| NID_commonName, peer_CN, 256); | |
| if(strcasecmp(peer_CN,host)) | |
| { | |
| cwmp_log_error("Common name doesn't match host name"); | |
| //return CWMP_ERROR; | |
| } | |
| return CWMP_OK; | |
| } | |
| //int http_socket_ssl_create(http_socket_t **news, SSL_CTX *ctx, pool_t * pool) | |
| //{ | |
| // int stat; | |
| // stat = http_socket_calloc(news, pool); | |
| // if (stat == CWMP_ERROR) | |
| // { | |
| // return CWMP_ERROR; | |
| // } | |
| // | |
| // if(! (*news)->use_ssl) | |
| // { | |
| // return CWMP_ERROR; | |
| // } | |
| // | |
| // (*news)->ssl = SSL_new(ctx); | |
| // return CWMP_OK; | |
| //} | |
| // | |
| #endif | |