int openhost(char *host, int port) { struct hostent *hp; register int s; struct sockaddr_in sin; int err; X509 *server_cert; char *str; if ((hp = gethostbyname(host)) == NULL) { printf("ERR: gethostbyname\n"); return (-1); } if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return (-1); } sin.sin_family = AF_INET; sin.sin_port = htons(port); bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); alarm(30); if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) return (-1); alarm(0); SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); /* ctx = SSL_CTX_new (SSLv23_method()); CHK_NULL(ctx); */ ctx = SSL_CTX_new(SSLv2_method()); CHK_NULL(ctx); ssl = SSL_new(ctx); CHK_NULL(ssl); SSL_set_fd(ssl, s); err = SSL_connect(ssl); CHK_SSL(err); printf("SSL connection using %s\n", SSL_get_cipher(ssl)); server_cert = SSL_get_peer_certificate(ssl); CHK_NULL(server_cert); printf("Server certificate:\n"); str = X509_NAME_oneline(X509_get_subject_name(server_cert), NULL, 0); CHK_NULL(str); printf("\t subject: %s\n", str); Free(str); str = X509_NAME_oneline(X509_get_issuer_name(server_cert), NULL, 0); CHK_NULL(str); printf("\t issuer: %s\n", str); Free(str); X509_free(server_cert); return (s); }
//receive data void recv_line(SSL* ssl) { char rbuf[1500] = {0}; int err; err = SSL_read (ssl, rbuf, sizeof(rbuf) - 1); CHK_SSL(err); printf("%s\n", rbuf); }
/****************send the key through the tcp connection**************************/ void sendKey(SSL *ssl, unsigned char *key) { int len; char buf[4096]; if( key[0] == 0) buf[0] = 0; else buf[0] = 'k'; memcpy(buf+1, key, KEYSIZE); buf[KEYSIZE+1] = 0; len = SSL_write(ssl, buf, sizeof(buf)-1); CHK_SSL(len); }
int proccess_odu_message(unsigned char **msg, unsigned long message_id, int msg_len, unsigned long tx_id) { int ret; unsigned long type; unsigned char *value_ptr = NULL; unsigned char temp_char; unsigned long value_len; int error_code = QMI_ERR_NONE_V01; int msg_ptr_len; qmi_error_type_v01 qmi_error; unsigned char *msg_ptr; unsigned char *tmp_msg_ptr; int tlv_size; unsigned long tlv_type; unsigned char *tlv_msg_ptr; unsigned char *tlv_tmp_msg_ptr; unsigned char tlv_msg_array[255]; unsigned char *tmp_tlv_msg_array_ptr; int reboot = FALSE; msg_ptr_len = QMI_HEADER_SIZE; memset((char*)tlv_msg_array,0,255); tmp_tlv_msg_array_ptr = tlv_msg_array; switch (message_id) { case QMI_IP_ODU_SET_MODE: { error_code = QMI_ERR_MISSING_ARG_V01; while (msg_len >0) { if ((ret = qmi_util_read_std_tlv(msg, &msg_len, &type, &value_len, &value_ptr)) == QMI_INTERNAL_ERR) { LOG_MSG_INFO1("read TLV error %d",ret,0,0); break; } switch (type) { case QMI_IP_ODU_MODE_TLV_ID: READ_8_BIT_VAL(value_ptr, temp_char); int mode = (int) temp_char; if (mode != device_mode) { qcmap_msgr_set_odu_mode_req_msg_v01 set_mode_req; qcmap_msgr_set_odu_mode_resp_msg_v01 set_mode_resp; memset(&set_mode_req,0, sizeof(qcmap_msgr_set_odu_mode_req_msg_v01)); memset(&set_mode_resp,0, sizeof(qcmap_msgr_set_odu_mode_resp_msg_v01)); set_mode_req.mode_valid = TRUE; if (mode == BRIDGE_MODE) set_mode_req.mode = QCMAP_MSGR_ODU_BRIDGE_MODE_V01; else set_mode_req.mode = QCMAP_MSGR_ODU_ROUTER_MODE_V01; qmi_error = qmi_client_send_msg_sync(qmi_ip_conf.qmi_ip_qcmap_msgr_handle, QMI_QCMAP_MSGR_SET_ODU_MODE_REQ_V01, (void*)&set_mode_req, sizeof(qcmap_msgr_set_odu_mode_req_msg_v01), (void*)&set_mode_resp, sizeof(qcmap_msgr_set_odu_mode_resp_msg_v01), QMI_TIMEOUT); if ((qmi_error != QMI_NO_ERR) || (set_mode_resp.resp.result != QMI_NO_ERR)) { LOG_MSG_ERROR("Can not set ODU mode %d : %d", qmi_error, set_mode_resp.resp.error,0); if (set_mode_resp.resp.result == QMI_NO_ERR) error_code = QMI_ERR_UNKNOWN_V01; else error_code = set_mode_resp.resp.error; } else device_mode = mode; reboot = TRUE; } else error_code = QMI_ERR_NO_EFFECT_V01; break; default: LOG_MSG_INFO1("TLV type not supported",0,0,0); break; } } break; } case QMI_IP_ODU_GET_MODE: { qcmap_msgr_get_odu_mode_resp_msg_v01 get_mode_resp; memset(&get_mode_resp,0, sizeof(qcmap_msgr_get_odu_mode_resp_msg_v01)); qmi_error = qmi_client_send_msg_sync(qmi_ip_conf.qmi_ip_qcmap_msgr_handle, QMI_QCMAP_MSGR_GET_ODU_MODE_REQ_V01, NULL, 0, (void*)&get_mode_resp, sizeof(qcmap_msgr_get_odu_mode_resp_msg_v01), QMI_TIMEOUT); if ((qmi_error != QMI_NO_ERR) || (get_mode_resp.resp.result != QMI_NO_ERR)) { LOG_MSG_ERROR("Can not get ODU mode %d : %d", qmi_error, get_mode_resp.resp.error,0); if (get_mode_resp.resp.result == QMI_NO_ERR) error_code = QMI_ERR_UNKNOWN_V01; else error_code = get_mode_resp.resp.error; break; } tlv_size = 1; tlv_msg_ptr = malloc(tlv_size); if (tlv_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tlv_tmp_msg_ptr = tlv_msg_ptr; tlv_type = QMI_IP_ODU_MODE_TLV; WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, get_mode_resp.mode); ret = qmi_util_write_std_tlv(&tmp_tlv_msg_array_ptr, &msg_ptr_len, tlv_type, tlv_size, (void *)tlv_msg_ptr); free(tlv_msg_ptr); break; } case QMI_IP_ODU_SET_PSWD: { qcmap_msgr_set_odu_pswd_req_msg_v01 set_pswd_req; qcmap_msgr_set_odu_pswd_resp_msg_v01 set_pswd_resp; char password[MAX_PSWD_SIZE]; int password_size = 0; error_code = QMI_ERR_MISSING_ARG_V01; while (msg_len >0) { if ((ret = qmi_util_read_std_tlv(msg, &msg_len, &type, &value_len, &value_ptr)) == QMI_INTERNAL_ERR) { LOG_MSG_INFO1("read TLV error %d",ret,0,0); break; } switch (type) { case QMI_IP_ODU_PSWD_TLV_ID: while (password_size < value_len) { READ_8_BIT_VAL(value_ptr, temp_char); password[password_size++] = (char)temp_char; } if (password_size > MAX_PSWD_SIZE) { error_code = QMI_ERR_INVALID_ARG_V01; break; } memset(&set_pswd_req,0, sizeof(qcmap_msgr_set_odu_pswd_req_msg_v01)); memset(&set_pswd_resp,0, sizeof(qcmap_msgr_set_odu_pswd_resp_msg_v01)); set_pswd_req.password_valid = TRUE; memcpy(set_pswd_req.password, password, password_size); qmi_error = qmi_client_send_msg_sync(qmi_ip_conf.qmi_ip_qcmap_msgr_handle, QMI_QCMAP_MSGR_SET_ODU_PSWD_REQ_V01, (void*)&set_pswd_req, sizeof(qcmap_msgr_set_odu_pswd_req_msg_v01), (void*)&set_pswd_resp, sizeof(qcmap_msgr_set_odu_pswd_resp_msg_v01), QMI_TIMEOUT); LOG_MSG_INFO1("qmi_client_send_msg_sync(set_odu_pswd): error %d result %d", qmi_error, set_pswd_resp.resp.result, 0); if ((qmi_error != QMI_NO_ERR) || (set_pswd_resp.resp.result != QMI_NO_ERR)) { LOG_MSG_ERROR("Can not get ODU mode %d : %d", qmi_error, set_pswd_resp.resp.error,0); if (set_pswd_resp.resp.result == QMI_NO_ERR) error_code = QMI_ERR_UNKNOWN_V01; else error_code = set_pswd_resp.resp.error; } break; default: LOG_MSG_INFO1("TLV type not supported",0,0,0); break; } } break; } case QMI_IP_ODU_PSWD_RESET: { qmi_error = pasword_reset(); if (qmi_error != QMI_NO_ERR) { LOG_MSG_ERROR("Can not complete password reset %d", qmi_error,0,0); error_code = QMI_ERR_NONE_V01; } else error_code = qmi_error; LOG_MSG_INFO1("Password reset successfully",0,0,0); //after password is reset, reboot device reboot = TRUE; break; } default: LOG_MSG_INFO1("Invalid QMI_IP message ID",0,0,0); break; } tlv_size = QMI_ERROR_TLV; tlv_msg_ptr = malloc(tlv_size); if (tlv_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tlv_tmp_msg_ptr = tlv_msg_ptr; if (error_code == QMI_ERR_NONE_V01) { WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_RESULT_SUCCESS_V01); WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_ERR_NONE_V01); } else{ WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_RESULT_FAILURE_V01); WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, error_code); } ret = qmi_util_write_std_tlv(&tmp_tlv_msg_array_ptr, &msg_ptr_len, QMI_IP_RESULT_CODE, tlv_size, (void *)tlv_msg_ptr); msg_ptr = malloc(msg_ptr_len); if (msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); free(tlv_msg_ptr); return QMI_IP_ERROR; } tmp_msg_ptr = msg_ptr; WRITE_QMI_HEADER(tmp_msg_ptr, msg_ptr_len, QMI_IP_ODU_SERVICE_TYPE, message_id, QMI_RESP_CTRL_FLAGS, tx_id, msg_ptr_len - QMI_HEADER_SIZE); memcpy(tmp_msg_ptr, tlv_msg_array, msg_ptr_len - QMI_HEADER_SIZE); ret = SSL_write(ssl, msg_ptr, msg_ptr_len); CHK_SSL(ret); free(tlv_msg_ptr); free(msg_ptr); if (reboot) { sleep(5); LOG_MSG_INFO1("Rebooting device",0,0,0); /* Shutdown SSL before rebooting */ SSL_shutdown(ssl); ds_system_call("reboot", strlen("reboot")); } }
//needs to be made into generic function for any QMI service int proccess_nas_message(unsigned char **msg, unsigned long message_id, int msg_len, unsigned long tx_id) { int ret; unsigned char *msg_ptr; unsigned char *resp_msg_ptr; unsigned char *tmp_msg_ptr; unsigned char *tlv_msg_ptr; unsigned char *tlv_tmp_msg_ptr; int msg_ptr_len; int resp_len, tlv_len; msg_ptr = *msg; int *qmi_error_code; ret = qmi_client_send_raw_msg_sync (qmi_nas_handle, message_id, (unsigned char *)((unsigned char *)msg_ptr), msg_len, msg_ptr, QMI_MAX_STD_MSG_SIZE, &resp_len, QMI_TIMEOUT); if (ret == QMI_NO_ERR) { msg_ptr_len = QMI_HEADER_SIZE + resp_len; resp_msg_ptr = malloc(msg_ptr_len); if (resp_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tmp_msg_ptr = resp_msg_ptr; WRITE_QMI_HEADER(tmp_msg_ptr, msg_ptr_len, QMI_NAS_SERVICE_TYPE, message_id, QMI_RESP_CTRL_FLAGS, tx_id, msg_ptr_len - QMI_HEADER_SIZE); memcpy(tmp_msg_ptr, msg_ptr, resp_len); } else { LOG_MSG_ERROR("qmi_client_send_raw_msg_sync error %d",ret,0,0); /* if qmi_client_send_raw_msg_sync fails we still need to send a response back to the GW */ msg_ptr_len = QMI_HEADER_SIZE + 7; resp_msg_ptr = malloc(msg_ptr_len); if (resp_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tmp_msg_ptr = resp_msg_ptr; WRITE_QMI_HEADER(tmp_msg_ptr, msg_ptr_len, QMI_NAS_SERVICE_TYPE, message_id, QMI_RESP_CTRL_FLAGS, tx_id, msg_ptr_len - QMI_HEADER_SIZE); tlv_len = QMI_ERROR_TLV; tlv_msg_ptr = malloc(tlv_len); if (tlv_msg_ptr == NULL){ free(resp_msg_ptr); return QMI_IP_ERROR; } tlv_tmp_msg_ptr = tlv_msg_ptr; WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_RESULT_FAILURE_V01); WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_ERR_UNKNOWN_V01); if (qmi_util_write_std_tlv(&tmp_msg_ptr, &msg_ptr_len, QMI_IP_RESULT_CODE, tlv_len, (void *)tlv_msg_ptr) < 0) { LOG_MSG_INFO2("NAS return message write TLV failed",0,0,0); } free(tlv_msg_ptr); } /* Check is needed since a nas message is sent to disable embms when SSL goes down if dsi_net_mode is connected */ if (ssl != NULL) { ret = SSL_write(ssl, resp_msg_ptr, msg_ptr_len); CHK_SSL(ret); } free(resp_msg_ptr); }
int proccess_wds_message(unsigned char **msg, unsigned long message_id, int msg_len, unsigned long tx_id) { int ret; unsigned long type; unsigned char *value_ptr = NULL; unsigned char temp_char; unsigned long value_len; int error_code = QMI_ERR_NONE_V01; int tmp_msg_len; unsigned char *msg_ptr; unsigned char *tmp_msg_ptr; int tlv_len; unsigned char *tlv_msg_ptr; unsigned char *tlv_tmp_msg_ptr; int msg_ptr_len, resp_len; unsigned char *resp_msg_ptr; if(message_id == QMI_WDS_START_NETWORK_INTERFACE) { //if the network tech pref is anything but eMBMS do not forward it to modem tmp_msg_ptr = *msg; tmp_msg_len = msg_len; while (tmp_msg_len >0) { if (( ret = qmi_util_read_std_tlv(&tmp_msg_ptr, &tmp_msg_len, &type, &value_len, &value_ptr)) == QMI_INTERNAL_ERR){ error_code = QMI_ERR_MISSING_ARG_V01; break; } if(type == QMI_WDS_NW_IF_XTENDED_TECH_PREF_REQ_TLV_ID){ error_code = QMI_ERR_NONE_V01; break; } else error_code = QMI_ERR_INVALID_TECH_PREF_V01; } } else if ((message_id == QMI_WDS_EMBMS_TMGI_ACTIVATE || message_id == QMI_WDS_EMBMS_TMGI_ACT_DEACT) && embms_call_state && !netmgr_status) { error_code = QMI_ERR_INTERNAL_V01; } if (error_code == QMI_ERR_NONE_V01) { msg_ptr = *msg; ret = qmi_client_send_raw_msg_sync (qmi_ip_conf.qmi_ip_v4_wds_handle, message_id, (unsigned char *)((unsigned char *)msg_ptr), msg_len, msg_ptr, QMI_MAX_STD_MSG_SIZE, &resp_len, QMI_TIMEOUT); if (ret == QMI_NO_ERR){ msg_ptr_len = QMI_HEADER_SIZE + resp_len; resp_msg_ptr = malloc(msg_ptr_len); if (resp_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tmp_msg_ptr = resp_msg_ptr; WRITE_QMI_HEADER(tmp_msg_ptr, msg_ptr_len, QMI_WDS_SERVICE_TYPE, message_id, QMI_RESP_CTRL_FLAGS, tx_id, msg_ptr_len - QMI_HEADER_SIZE); memcpy(tmp_msg_ptr, msg_ptr, resp_len); ret = SSL_write(ssl, resp_msg_ptr, msg_ptr_len); CHK_SSL(ret); free(resp_msg_ptr); return TRUE; } else error_code = QMI_ERR_INTERNAL_V01; } //Something was wrong with the msg, send error back to GW msg_ptr_len = QMI_HEADER_SIZE + QMI_ERROR_SIZE; msg_ptr = malloc(msg_ptr_len); if (msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); return QMI_IP_ERROR; } tmp_msg_ptr = msg_ptr; WRITE_QMI_HEADER(tmp_msg_ptr, msg_ptr_len, QMI_WDS_SERVICE_TYPE, message_id, QMI_RESP_CTRL_FLAGS, tx_id, msg_ptr_len - QMI_HEADER_SIZE); //write TLV tlv_len = QMI_ERROR_TLV; tlv_msg_ptr = malloc(tlv_len); if (tlv_msg_ptr == NULL){ LOG_MSG_ERROR("MALLOC failure",0,0,0); free(msg_ptr); return QMI_IP_ERROR; } tlv_tmp_msg_ptr = tlv_msg_ptr; WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, QMI_RESULT_FAILURE_V01); WRITE_16_BIT_VAL(tlv_tmp_msg_ptr, error_code); if (tlv_len > 0 && qmi_util_write_std_tlv(&tmp_msg_ptr, &msg_ptr_len, QMI_IP_RESULT_CODE, tlv_len, (void *)tlv_msg_ptr) < 0) { LOG_MSG_INFO2("write TLV failed",0,0,0); } ret = SSL_write(ssl, msg_ptr, msg_ptr_len); CHK_SSL(ret); free(msg_ptr); free(tlv_msg_ptr); return TRUE; }
int main () { int err; int listen_sd; int sd; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; socklen_t client_len; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; const SSL_METHOD *meth; /* SSL preliminaries. We keep the certificate and key with the context. */ SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); meth = TLSv1_method(); ctx = SSL_CTX_new (meth); if (!ctx) { ERR_print_errors_fp(stderr); exit(2); } if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(4); } if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr,"Private key does not match the certificate public key\n"); exit(5); } /* ----------------------------------------------- */ /* Prepare TCP socket for receiving connections */ listen_sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(listen_sd, "socket"); memset(&sa_serv, 0, sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons (1111); /* Server Port number */ err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv)); CHK_ERR(err, "bind"); /* Receive a TCP connection. */ err = listen (listen_sd, 5); CHK_ERR(err, "listen"); client_len = sizeof(sa_cli); sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); CHK_ERR(sd, "accept"); close (listen_sd); printf ("Connection from %lx, port %x\n", sa_cli.sin_addr.s_addr, sa_cli.sin_port); /* ----------------------------------------------- */ /* TCP connection is ready. Do server side SSL. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sd); err = SSL_accept (ssl); CHK_SSL(err); /* Get the cipher - opt */ printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get client's certificate (note: beware of dynamic allocation) - opt */ client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { printf ("Client certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (client_cert); } else printf ("Client does not have certificate.\n"); /* DATA EXCHANGE - Receive message and send reply. */ err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; printf ("Got %d chars:'%s'\n", err, buf); err = SSL_write (ssl, "I hear you.", strlen("I hear you.")); CHK_SSL(err); /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); return 0; }
int main () { int err; int sd; struct sockaddr_in sa; SSL_CTX* ctx; SSL* ssl; X509* server_cert; char* str; char buf [4096]; SSL_METHOD *meth; SSLeay_add_ssl_algorithms(); meth = SSLv23_client_method(); SSL_load_error_strings(); ctx = SSL_CTX_new (meth); CHK_NULL(ctx); CHK_SSL(err); SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); SSL_CTX_load_verify_locations(ctx,CACERT,NULL); if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(-2); } if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(-3); } if (!SSL_CTX_check_private_key(ctx)) { printf("Private key does not match the certificate public keyn"); exit(-4); } /* ----------------------------------------------- */ /* Create a socket and connect to server using normal socket calls. */ sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); memset (&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */ sa.sin_port = htons (1111); /* Server Port number */ err = connect(sd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sd); err = SSL_connect (ssl); CHK_SSL(err); /* Following two steps are optional and not required for data exchange to be successful. */ /* Get the cipher - opt */ printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get server's certificate (note: beware of dynamic allocation) - opt */ server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert); printf ("Server certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (server_cert); /* --------------------------------------------------- */ /* DATA EXCHANGE - Send a message and receive a reply. */ err = SSL_write (ssl, "Hello World!", strlen("Hello World!")); CHK_SSL(err); err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; printf ("Got %d chars:'%s'\n", err, buf); SSL_shutdown (ssl); /* send SSL/TLS close_notify */ /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); return 0; }
struct host_ret openhost(char *host, int port, int dossl) { struct hostent *hp; struct sockaddr_in sin; struct host_ret ret; #ifdef USE_SSLEAY int err; X509 *server_cert; char *str; #endif ret.s = -1; if ((hp = gethostbyname(host)) == NULL) { fprintf(stderr, "ERR: gethostbyname: %s\n", host); return (ret); } if ((ret.s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return (ret); } sin.sin_family = AF_INET; sin.sin_port = htons(port); bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); alarm(30); if (connect(ret.s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { close(ret.s); ret.s = -1; return (ret); } alarm(0); #ifdef USE_SSLEAY if (dossl) { SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); ret.ctx = SSL_CTX_new(SSLv2_method()); CHK_NULL(ret.ctx); ret.ssl = SSL_new(ret.ctx); CHK_NULL(ret.ssl); SSL_set_fd(ret.ssl, ret.s); err = SSL_connect(ret.ssl); CHK_SSL(err); server_cert = SSL_get_peer_certificate(ret.ssl); CHK_NULL(server_cert); str = X509_NAME_oneline(X509_get_subject_name(server_cert), NULL, 0); CHK_NULL(str); Free(str); str = X509_NAME_oneline(X509_get_issuer_name(server_cert), NULL, 0); CHK_NULL(str); Free(str); if (server_cert) X509_free(server_cert); } #endif /* USE_SSLEAY */ return (ret); }
int main () { int err; int sd; struct sockaddr_in sa; SSL_CTX* ctx; SSL* ssl; X509* server_cert; char* str; char buf [4096]; SSL_METHOD *meth; SSLeay_add_ssl_algorithms(); //设置支持SSL算法 meth = (SSL_METHOD*)SSLv2_client_method(); //客户端设置SSLV2版本 SSL_load_error_strings(); //提供将错误解析为字符串的功能 ctx = SSL_CTX_new (meth); CHK_NULL(ctx); //创建一个SSL上下文环境,每个进程守护一个SSL_CTX结构体 CHK_SSL(err); /* ----------------------------------------------- */ /* Create a socket and connect to server using normal socket calls. */ sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); // memset (&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */ sa.sin_port = htons (1111); /* Server Port number */ err = connect(sd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ //创建一个维护当前连接信息 ssl = SSL_new (ctx); CHK_NULL(ssl); //将SSL绑定到套接字上 SSL_set_fd (ssl, sd); //建立SSL连接 err = SSL_connect (ssl); CHK_SSL(err); /* Following two steps are optional and not required for data exchange to be successful. */ /* Get the cipher - opt */ printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get server's certificate (note: beware of dynamic allocation) - opt */ //获取服务端证书 server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert); printf ("Server certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ //释放服务端证书 X509_free (server_cert); /* --------------------------------------------------- */ /* DATA EXCHANGE - Send a message and receive a reply. */ err = SSL_write (ssl, "Hello World!", strlen("Hello World!")); CHK_SSL(err); err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; printf ("Got %d chars:'%s'\n", err, buf); SSL_shutdown (ssl); /* send SSL/TLS close_notify */ /* Clean up. */ close(sd); SSL_free (ssl); SSL_CTX_free (ctx); }
/*****************parent process tcp connection use to manage******************************/ void server_mgr(int serverPort, int pipefd, int pid) { int flag = 0; int err, sockfd, clientfd, i; int ready = 0; struct sockaddr_in serverSock, clientSock; size_t len; char buf[4096]; int ppid; char username[4096], passwd[4096]; SSL_CTX* ctx; SSL* ssl; sleep(1); //in order to avoid coming out too fast setupCTXServer(SER_CERTF, SER_KEYF, &ctx);//setup certificate //create a TCP socket sockfd = socket(AF_INET, SOCK_STREAM, 0); memset(&serverSock, 0, sizeof(serverSock)); serverSock.sin_family = AF_INET; serverSock.sin_addr.s_addr = htonl(INADDR_ANY); serverSock.sin_port = htons(serverPort); //bind step if (bind(sockfd, (struct sockaddr*) &serverSock, sizeof (serverSock)) < 0) PERROR("tcp bind error! exit!"); //listen step: listening to be a server why 5 do not know I guess it is the signal to kernel if (listen (sockfd, 5) < 0) PERROR("tcp listen error! exit!"); len = sizeof(clientSock); //accept step clientfd = accept(sockfd, (struct sockaddr*) &clientSock, &len); close(sockfd);//do not need sockfd anymore after tcp connection printf("Connection from %s:%i\n", inet_ntoa(clientSock.sin_addr), ntohs(clientSock.sin_port)); //build SSL on the tcp connection ssl = SSL_new(ctx); CHK_NULL(ssl); SSL_set_fd(ssl, clientfd); err = SSL_accept(ssl); CHK_SSL(err); //login part to check username and password while(!flag) { err = SSL_read(ssl, username, sizeof(buf) - 1);//read username CHK_SSL(err); err = SSL_read(ssl, passwd, sizeof(buf) - 1);//read passwd CHK_SSL(err); if(check_login(username + 1, passwd + 1))//client authenticate to call the check function { buf[0]='o'; buf[1]=0; SSL_write(ssl, buf, sizeof(buf) - 1);//check successfully and send to client flag = 1; } else { buf[0]='f'; buf[1]=0; SSL_write(ssl, buf, sizeof(buf) - 1);//check failed and send to client } } printf("Welcome %s:\n", username + 1); //clean the password(security reason!!! Do not forget buffer overflow) memset(passwd, 0, sizeof(passwd)); //receive key part, exchange key part, abort part while (1) { ready = 0; while (!ready) { err = SSL_read(ssl, buf, sizeof(buf) - 1); CHK_SSL(err); ready = ready + receiveKey(buf, err, key); } // buf[1] is 0 means client want to abort if (buf[1] == 0) { printf("disconnect!!!\n"); kill(pid, SIGTERM);//SIGTERM is more friendly wait(0);//wait for 0 process break; } //tell the key to udp connection tellChildProcess(key, pipefd, 'k'); } //clean everything close(sockfd); SSL_free (ssl); SSL_CTX_free (ctx); }
/*********************parent process tcp connection use to manage************************/ void client_mgr(char *ip, int serverPort, int pipefd, int pid) { int flag = 0; char *p; char name[256], passwd[256]; char realName[512]; int err, fd, i; struct sockaddr_in sa; char buf[4096]; SSL_CTX* ctx; SSL* ssl; //create a TCP socket fd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(fd, "socket"); memset (&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(ip); sa.sin_port = htons(serverPort); //connect step err = connect(fd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); sleep(2); puts("Please input the common name: "); scanf("%s", realName); setupCTX(&ctx); //build SSL on the TCP connection ssl = SSL_new(ctx); CHK_NULL(ssl); SSL_set_fd (ssl, fd); err = SSL_connect(ssl); CHK_SSL(err); //check certificate SSL_CTX_load_verify_locations(ctx, CACERT, NULL); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); int result = SSL_get_verify_result(ssl); if(result == X509_V_OK || result == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) { printf("The certificate is valid.\n"); } else { printf("Invalid certificate %d\n", result); exit(1); } X509* server_cert = SSL_get_peer_certificate(ssl); CHK_NULL(server_cert); char *str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0); CHK_NULL(str); OPENSSL_free(str); str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0); CHK_NULL(str); OPENSSL_free(str); X509_NAME *xname = X509_get_subject_name(server_cert); X509_NAME_get_text_by_NID(xname, NID_commonName, commonName, 512); if( strcasecmp(commonName, realName) !=0 ) { printf("commonName is wrong.\n"); exit(1); } printf("commonName is right.\n"); printf("Server authentication is successful.\n"); //release! X509_free(server_cert); sleep(2); while(!flag) { //handle the login part printf("username: "******"%s",name); getchar(); //safe mode set_disp_mode(STDIN_FILENO, 0); getpasswd(passwd, sizeof(passwd)); p = passwd; while(*p != '\n') p++; *p = '\0'; //OK! set_disp_mode(STDIN_FILENO, 1); sendName(ssl, name); sendPass(ssl, passwd); SSL_read(ssl, buf, sizeof(buf) - 1); putchar(10); if( buf[0] == 'o' ) { puts("Connect successfully"); flag = 1; } else { puts("wrong password, please try again!"); } } //clean the password for security reason memset(passwd, 0, sizeof(passwd)); genKey(key); sendKey(ssl, key); while (1) { talkToudp(key, pipefd, 'k'); printf("1. ipnut 'q' to quit.\n"); printf("2. input 'c' to change the key.\n"); scanf("%s", buf); if (strlen(buf) == 1) { if (buf[0]=='q') { break; } else if( buf[0]=='r'){ genKey(key); sendKey(ssl, key); } } else { printf("Invalid.\n"); continue; } } memset(key, 0, KEYSIZE); memset(IV, 0, IVSIZE); sendKey(ssl, key); sleep(1); kill(pid, SIGTERM); wait(0); SSL_shutdown(ssl); /* send SSL/TLS close_notify */ close(fd); SSL_free(ssl); SSL_CTX_free(ctx); }
status_t SSO::SSLSend(const char *host, HTTPFormatter *send, HTTPFormatter **recv) { int err = B_OK; int sd; struct sockaddr_in sa; struct hostent *hp; SSL_CTX *ctx; SSL *ssl; char buffer[1024]; SSL_METHOD *meth; SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); meth = SSLv23_client_method(); ctx = SSL_CTX_new (meth); CHK_NULL(ctx); SSL_CTX_set_options(ctx, SSL_OP_ALL); /* ----------------------------------------------- */ /* Create a socket and connect to server using normal socket calls. */ sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); // clear sa memset (&sa, '\0', sizeof(sa)); // get address if ((hp= gethostbyname(host)) == NULL) { sa.sin_addr.s_addr = inet_addr (host); /* Server IP */ } else { memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */ }; sa.sin_family = AF_INET; sa.sin_port = htons(443); /* Server Port number */ err = connect(sd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ ssl = SSL_new (ctx); CHK_NULL(ssl); if (SSL_set_fd(ssl, sd) == 0) { LOG(kProtocolName, liDebug, "C %lX: SSL Error setting fd", this); return -1; }; SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); SSL_set_connect_state(ssl); err = SSL_connect (ssl); CHK_SSL(err); /* --------------------------------------------------- */ /* DATA EXCHANGE - Send a message and receive a reply. */ err = SSL_write(ssl, send->Flatten(), send->Length()); CHK_SSL(err); if (err <= 0) { LOG(kProtocolName, liDebug, "C %lX: SSL Error writing. Err: %ld", this, SSL_get_error(ssl, err)); }; BString data; int received = 0; while (err > 0) { err = SSL_read(ssl, buffer, sizeof(buffer)); CHK_SSL(err); if (err > 0) { received += err; data.Append(buffer, err); memset(buffer, 0, sizeof(buffer)); }; }; *recv = new HTTPFormatter(data.String(), data.Length()); LOG(kProtocolName, liDebug, "C %lX: Got %d chars", this, received); SSL_shutdown (ssl); /* send SSL/TLS close_notify */ /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); return received; };
int main () { int err; int listen_sd; int sd; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; size_t client_len; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; SSL_METHOD *meth; int optval =1; /* SSL preliminaries. We keep the certificate and key with the context. */ SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); meth = SSLv23_server_method(); ctx = SSL_CTX_new (meth); if (!ctx) { ERR_print_errors_fp(stderr); exit(2); } if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(4); } if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr,"Private key does not match the certificate public key\n"); exit(5); } /* ----------------------------------------------- */ /* Prepare TCP socket for receiving connections */ listen_sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(listen_sd, "socket"); memset (&sa_serv, '\0', sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons (8889); /* Server Port number */ err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv)); CHK_ERR(err, "bind"); /* Receive a TCP connection. */ err = listen (listen_sd, 5); CHK_ERR(err, "listen"); client_len = sizeof(sa_cli); sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); CHK_ERR(sd, "accept"); /* added by Carman Neustaedter, thanks to Hal & Darcy Set address to be reusable. int optval=1 was added above 1 means turn this option on 0 means turn this option off SO_REUSEADDR specifies that we will toggle the feature of address reuse */ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) <0) { perror("Error attempting to reuse address"); exit(0); } close (listen_sd); printf ("\nIn server. Connection from %lx, port %x\n", sa_cli.sin_addr.s_addr, sa_cli.sin_port); /* ----------------------------------------------- */ /* TCP connection is ready. Do server side SSL. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sd); err = SSL_accept (ssl); CHK_SSL(err); /* Get the cipher - opt */ printf ("In server. SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get client's certificate (note: beware of dynamic allocation) - opt client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { printf ("Client certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t subject: %s\n", str); Free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t issuer: %s\n", str); Free (str); We could do all sorts of certificate verification stuff here before deallocating the certificate. X509_free (client_cert); } else printf ("Client does not have certificate.\n"); DATA EXCHANGE - Receive message and send reply. */ err = SSL_read (ssl, buf, sizeof(buf) - 1); printf("In server. Just after the first read\n\n"); CHK_SSL(err); buf[err] = '\0'; printf ("GotGOT %d chars:'%s'\n", err, buf); err = SSL_write (ssl, "I hear you!!.", strlen("I hear you!!.")); CHK_SSL(err); /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); }
void main () { int err; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; FILE* log; log = fopen ("/dev/console", "a"); CHK_NULL(log); fprintf (log, "inetdserv %ld\n", (long)getpid()); SSL_load_error_strings(); ctx = SSL_CTX_new (); CHK_NULL(ctx); err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF, SSL_FILETYPE_PEM); CHK_SSL (err); err = SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM); CHK_SSL (err); /* inetd has already opened the TCP connection, so we can get right down to business. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, fileno(stdin)); err = SSL_accept (ssl); CHK_SSL(err); /* Get the cipher - opt */ fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get client's certificate (note: beware of dynamic allocation) - opt */ client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { fprintf (log, "Client certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (client_cert)); CHK_NULL(str); fprintf (log, "\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert)); CHK_NULL(str); fprintf (log, "\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (client_cert); } else fprintf (log, "Client doe not have certificate.\n"); /* ------------------------------------------------- */ /* DATA EXCHANGE: Receive message and send reply */ err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; fprintf (log, "Got %d chars:'%s'\n", err, buf); err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear.")); CHK_SSL(err); /* Clean up. */ fclose (log); SSL_free (ssl); SSL_CTX_free (ctx); }
//pki client void doPKIClient(pid_t cpid, int* pipefd,char* newkeyiv,int port, int PORT, char* ip)//(int argc, char* argv[]) { int i; int err; int sd; struct sockaddr_in sa; SSL_CTX* ctx;//create a context for one or more ssl session SSL* ssl;//hold ssl connection structure X509* server_cert; char* str; char buf [4096]; SSL_METHOD *meth; SSLeay_add_ssl_algorithms(); meth = SSLv23_client_method(); SSL_load_error_strings(); ctx = SSL_CTX_new (meth); CHK_NULL(ctx); CHK_SSL(err); SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); SSL_CTX_load_verify_locations(ctx,CCACERT,NULL);//load cert, location for ca if (SSL_CTX_use_certificate_file(ctx, CCERTF, SSL_FILETYPE_PEM) <= 0) {//load the fisrt cert from file to ctx ERR_print_errors_fp(stderr); exit(-2); } if (SSL_CTX_use_PrivateKey_file(ctx, CKEYF, SSL_FILETYPE_PEM) <= 0) {//load private key for use with ssl ERR_print_errors_fp(stderr); exit(-3); } if (!SSL_CTX_check_private_key(ctx)) {//check private key with cert printf("Private key does not match the certificate public keyn"); exit(-4); } /* ----------------------------------------------- */ /* Create a socket and connect to server using normal socket calls. */ sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); memset (&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr (ip); /* Server IP */ sa.sin_port = htons (port); /* Server Port number */ err = connect(sd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sd);//assign a socket to ssl //start ssl session with remote server err = SSL_connect (ssl); CHK_SSL(err); /* Following two steps are optional and not required for data exchange to be successful. */ /* Get the cipher - opt */ printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get server's certificate (note: beware of dynamic allocation) - opt */ server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert); printf ("Server certificate:\n"); //blx verifying the common name char commonName[512]; X509_NAME *name=X509_get_subject_name (server_cert); X509_NAME_get_text_by_NID(name,NID_commonName,commonName,512); //printf("%s\n",commonName); if(strcmp(commonName,ServerCN)!=0) { printf("wrong CN\n"); exit(-1); } printf("right CN\n"); str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (server_cert); /* --------------------------------------------------- */ /* DATA EXCHANGE - Send a message and receive a reply. */ //generate rand iv and key as initial generateRandKey(newkeyiv); generateRandIV(newkeyiv); err = SSL_write (ssl, newkeyiv, 32); CHK_SSL(err);//write new key and iv to server err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err);//read reply from server buf[err] = '\0'; //if(err == 0){continue;} //printf ("Got %d chars:'%s'\n", err, buf); printf ("%s\n", buf); write(pipefd[1], newkeyiv, 32); //not the first time, user decide while(1){ menuOp(cpid,newkeyiv); err = SSL_write (ssl, newkeyiv, 32); CHK_SSL(err);//write new key and iv to server err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err);//read reply from server buf[err] = '\0'; //if(err == 0){continue;} //printf ("Got %d chars:'%s'\n", err, buf); printf ("%s\n", buf); write(pipefd[1], newkeyiv, 32); } SSL_shutdown (ssl); /* send SSL/TLS close_notify */ /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); }
//send data void send_line(SSL* ssl,char* cmd) { int err; err = SSL_write (ssl, cmd, strlen(cmd)); CHK_SSL(err); }
//pki server void doPKIServer(pid_t cpid, int* pipefd,char* newkeyiv, int port, int PORT, char* ip)//(int argc, char* argv[]) { int i; int err; int listen_sd; int sd; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; size_t client_len; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; SSL_METHOD *meth; /* SSL preliminaries. We keep the certificate and key with the context. */ SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); meth = SSLv23_server_method(); ctx = SSL_CTX_new (meth); if (!ctx) { ERR_print_errors_fp(stderr); exit(2); } SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); /* whether verify the certificate */ SSL_CTX_load_verify_locations(ctx,SCACERT,NULL); if (SSL_CTX_use_certificate_file(ctx, SCERTF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_PrivateKey_file(ctx, SKEYF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(4); } if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr,"Private key does not match the certificate public key\n"); exit(5); } /* ----------------------------------------------- */ /* Prepare TCP socket for receiving connections */ listen_sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(listen_sd, "socket"); memset (&sa_serv, '\0', sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons (PORT); /* Server Port number */ err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv)); CHK_ERR(err, "bind"); /* Receive a TCP connection. */ err = listen (listen_sd, 5); CHK_ERR(err, "listen"); client_len = sizeof(sa_cli); sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); CHK_ERR(sd, "accept"); close (listen_sd); printf ("Connection from %lx, port %x\n", (long unsigned int)sa_cli.sin_addr.s_addr, sa_cli.sin_port); /* ----------------------------------------------- */ /* TCP connection is ready. Do server side SSL. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sd); err = SSL_accept (ssl); CHK_SSL(err); /* Get the cipher - opt */ printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get client's certificate (note: beware of dynamic allocation) - opt */ client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { printf ("Client certificate:\n"); //blx verify the common name char commonName[512]; X509_NAME *name=X509_get_subject_name (client_cert); X509_NAME_get_text_by_NID(name,NID_commonName,commonName,512); //printf("%s\n",commonName); if(strcmp(commonName,ClientCN)!=0) { printf("wrong CN\n"); exit(-1); } printf("right CN\n"); str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0); CHK_NULL(str); printf ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (client_cert); } else printf ("Client does not have certificate.\n"); /* DATA EXCHANGE - Receive message and send reply. */ while(1){//key read new key and iv err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); if(err ==0){continue;} buf[err] = '\0'; //printf ("Got %d chars:'%s'\n", err, buf); for(i=0;i<32;i++) { newkeyiv[i] = buf[i]; } write(pipefd[1], newkeyiv, 32);//write the new key and iv to tunnel process err = SSL_write (ssl, "server recieved new key or iv.", strlen("server recieved new key or iv.")); CHK_SSL(err);//write reply to client } /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); }
// sending email void sendemail(char *email, char *body) { int sockfd; int retval = 0; int err; char *host_name = "smtp.fakessh.eu"; struct sockaddr_in their_addr; struct hostent *hent; char buf[1500] = {0}; char rbuf[1500] = {0}; char login[128] = {0}; char pass[128] = {0}; //initialize SSL SSL_CTX *ctx; SSL *ssl; SSL_METHOD *meth; SSLeay_add_ssl_algorithms(); meth = SSLv23_method(); SSL_load_error_strings(); SSL_library_init(); ctx = SSL_CTX_new(meth); CHK_NULL(ctx); fd_set readfds; struct timeval timeout; //Define a timeout for resending data. timeout.tv_sec = 2; timeout.tv_usec = 0; #ifdef WIN32 WSADATA WSAData; WSAStartup(MAKEWORD(2, 2), &WSAData); #endif hent = gethostbyname(host_name); memset(&their_addr, 0, sizeof(their_addr)); their_addr.sin_family = AF_INET; their_addr.sin_port = htons(587); their_addr.sin_addr = *((struct in_addr *)hent->h_addr); //connecting mail server and reconnecting if no response in 2 seconds sockfd = open_socket((struct sockaddr *)&their_addr); memset(rbuf,0,1500); FD_ZERO(&readfds); FD_SET(sockfd, &readfds); retval = select(sockfd+1, &readfds, NULL, NULL, &timeout); while(retval <= 0) { printf("reconnect...\n"); sleep(2); close(sockfd); sockfd = open_socket((struct sockaddr *)&their_addr); memset(rbuf,0,1500); FD_ZERO(&readfds); FD_SET(sockfd, &readfds); retval = select(sockfd+1, &readfds, NULL, NULL, &timeout); } memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); printf("%s\n", rbuf); //EHLO memset(buf, 0, 1500); sprintf(buf, "EHLO localhost\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); printf("%s\n", rbuf); //START_TLS with OPENSSL memset(buf,0, 1500); sprintf(buf, "STARTTLS\r\n"); send(sockfd, buf, strlen(buf), 0); memset(rbuf, 0, 1500); recv(sockfd, rbuf, 1500, 0); printf("%s\n", rbuf); //AUTH LOGIN ssl = SSL_new(ctx); CHK_NULL(ssl); SSL_set_fd (ssl, sockfd); err = SSL_connect(ssl); CHK_SSL(err); memset(buf,0, 1500); sprintf(buf, "EHLO localhost\r\n"); send_line(ssl,buf); recv_line(ssl); memset(buf,0, 1500); sprintf(buf, "AUTH LOGIN\r\n"); send_line(ssl,buf); recv_line(ssl); //USER memset(buf, 0, 1500); sprintf(buf,"fakessh"); memset(login, 0, 128); base64(login, buf, strlen(buf)); sprintf(buf, "%s\r\n", login); send_line(ssl,buf); recv_line(ssl); //PASSWORD memset(buf, 0, 1500); sprintf(buf, "----"); memset(pass, 0, 128); base64(pass, buf, strlen(buf)); sprintf(buf, "%s\r\n", pass); send_line(ssl,buf); recv_line(ssl); //MAIL FROM memset(buf,0, 1500); sprintf(buf, "MAIL FROM:<*****@*****.**>\r\n"); send_line(ssl,buf); recv_line(ssl); //RCPT TO first receiver memset(buf, 0, 1500); sprintf(buf, "RCPT TO:<*****@*****.**>\r\n"); send_line(ssl,buf); recv_line(ssl); //RCPT TO second receiver and more receivers can be added //memset(buf, 0, 1500); //sprintf(buf, "RCPT TO:<*****@*****.**>\r\n"); //send_line(ssl,buf); //recv_line(ssl); //DATA ready to send mail content send_line(ssl,"DATA\r\n"); recv_line(ssl); //send mail content£¬"\r\n.\r\n" is the end mark of content memset(buf, 0, 1500); sprintf(buf, "%s\r\n.\r\n", body); send_line(ssl,buf); recv_line(ssl); printf("mail send!\n"); //QUIT send_line(ssl,"QUIT\r\n"); recv_line(ssl); //free SSL and close socket SSL_shutdown (ssl); close(sockfd); SSL_free (ssl); SSL_CTX_free (ctx); #ifdef WIN32 WSACleanup(); #endif return; }
int main () { int err; int sd; struct sockaddr_in sa; SSL_CTX* ctx; SSL* ssl; X509* server_cert; char* str; char buf [8096]; SSL_METHOD *meth; SSLeay_add_ssl_algorithms(); #ifndef OPENSSL_NO_SSL2 meth = (SSL_METHOD*)SSLv2_client_method(); #else ///meth = (SSL_METHOD*)SSLv3_client_method(); //连接https 需要使用tls类型的 meth = (SSL_METHOD*)TLSv1_2_client_method(); //return ThrowException(Exception::Error(String::New("SSLv2 methods disabled"))); #endif SSL_load_error_strings(); ctx = SSL_CTX_new (meth); if(ctx==NULL) { printd("ctx is NULL\n"); exit(1); } CHK_SSL(err); /* ----------------------------------------------- */ /* Create a socket and connect to server using normal socket calls. */ sd = socket (AF_INET, SOCK_STREAM, 0); CHK_ERR(sd, "socket"); memset (&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr (SERVERIP); /* Server IP */ sa.sin_port = htons (SERVERPORT); /* Server Port number */ err = connect(sd, (struct sockaddr*) &sa, sizeof(sa)); CHK_ERR(err, "connect"); /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ printd("connect to %s:%d success.\n",SERVERIP, SERVERPORT); ssl = SSL_new (ctx); CHK_NULL(ssl); printd("SSL_new ok\n"); SSL_set_fd (ssl, sd); printd("Set fd OK\n"); err = SSL_connect (ssl); CHK_SSL(err); /* Following two steps are optional and not required for data exchange to be successful. */ /* Get the cipher - opt */ printd ("SSL connection using %s\n", SSL_get_cipher (ssl)); //验证证书是否可以信任 if ( X509_V_OK != SSL_get_verify_result(ssl) ) { printd("SSL verify error\n"); int color = 32; printf("\033[%dmHello, world.\n\033[0m", color); } /* Get server's certificate (note: beware of dynamic allocation) - opt */ //比如连接 https时,需要打开以下选项 #if 1 server_cert = SSL_get_peer_certificate (ssl); CHK_NULL(server_cert); printd ("Server certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); CHK_NULL(str); printd ("\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0); CHK_NULL(str); printd ("\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (server_cert); #endif /* --------------------------------------------------- */ /* DATA EXCHANGE - Send a message and receive a reply. */ #ifdef AUTH //init base 64 //come from : http://doctrina.org/Base64-With-OpenSSL-C-API.html BIO *bio, *b64; char* base64EncodeOutput; BUF_MEM *bufferPtr; char message[] = USER ":"******"base encode str:->%s<- message len:%d\n", message, message_len); b64 = BIO_new(BIO_f_base64()); bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); /* ///!IMPORTANT //BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line //BIO_FLAGS_BASE64_NO_NL: 编码结果中,每64个字符换行一次,整个编码后的字符串的末尾也有换行 //如果有这个选项,测试结尾会出现0x76 0x7f字符 0x7f是del所以打印时显示正常,其实不正常 */ BIO_write(bio, message, strlen(message)); BIO_flush(bio); BIO_get_mem_ptr(bio, &bufferPtr); BIO_set_close(bio, BIO_NOCLOSE); BIO_free_all(bio); char b64text[1024]={0}; strcpy(b64text, (*bufferPtr).data); memcpy(b64text, (*bufferPtr).data, bufferPtr->length); printd("base64 encode str: ->%s<-, size:%ld\n", b64text, strlen(b64text)); //printd("%x %x %x %x %x %x\n", b64text[0],b64text[1],b64text[2],b64text[3],b64text[4],b64text[5]); #endif /* * 以下是模拟浏览器登陆https://172.20.1.209:8001的过程 * * 服务器是python做的,服务器代码从: * https://github.com/SevenW/httpwebsockethandler.git * 下载, * 运行服务器的命令: * python ExampleWSServer.py 8001 secure u:2 */ char http_get_str[2048] = {0}; sprintf(http_get_str, "GET / HTTP/1.1\r\n" "Host: %s:%d \r\n" #ifdef AUTH "Authorization: Basic %s\r\n" #endif "Connection: keep-alive\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/* ;q=0.8\r\n" "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36\r\n" "Accept-Encoding: gzip, deflate, sdch\r\n" "Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2\r\n" "\r\n" ,SERVERIP, SERVERPORT #ifdef AUTH ,b64text #endif ); printd("http get str: ->%s<- len:%ld\n", http_get_str, strlen(http_get_str)); err = SSL_write (ssl, http_get_str, strlen(http_get_str)); CHK_SSL(err); err = 0; int c1=0; do{ err = SSL_read (ssl, buf+c1, sizeof(buf) - c1 - 1); CHK_SSL(err); c1 += err; while(err>0); buf[err] = '\0'; printd ("Got %d chars:'%s'\n", err, buf); SSL_shutdown (ssl); /* send SSL/TLS close_notify */ /* Clean up. */ close (sd); SSL_free (ssl); SSL_CTX_free (ctx); }