blob: 888d433c9479e28023ecba27ac95f1e943911687 [file] [log] [blame]
#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