#include #include #include #include #include "agent_ssl.h" #define FAIL -1 /*---------------------------------------------------------------------*/ /*--- OpenConnection - create socket and connect to server. ---*/ /*---------------------------------------------------------------------*/ int connect_to_rmps(const char *hostname, int port) { int sd; struct hostent *host; struct sockaddr_in addr; if ((host = gethostbyname(hostname)) == NULL) { perror(hostname); return 0; } sd = socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = *(long*)(host->h_addr); if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) == FAIL) { close(sd); return 0; } return sd; } /*----------------------------------*/ /*--- Initialize the SSL engine. ---*/ /*----------------------------------*/ SSL_CTX* init_ctx(void) { SSL_CTX *ctx; char ciphers[2048]; //OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ //OpenSSL_add_all_ciphers(); /* Load cryptos, et.al. */ SSL_load_error_strings(); /* Bring in and register error messages */ SSL_library_init(); ctx = SSL_CTX_new(TLS_method()); /* Create new context */ ciphers[0] = 0; SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); strcat(ciphers, "-ALL"); if (!SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256:AES256-SHA")) { fprintf(stderr, "Failed to set the cipher list. Exiting...\n"); return NULL; } if (ctx == NULL) { ERR_print_errors_fp(stderr); return NULL; } return ctx; } int 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); fprintf(stderr, "-Error with certificate at depth: %i\n", depth); X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); fprintf(stderr, " issuer = %s\n", data); X509_NAME_oneline(X509_get_subject_name(cert), data, 256); fprintf(stderr, " subject = %s\n", data); fprintf(stderr, " err %i:%s\n", err, X509_verify_cert_error_string(err) ); } return ok; } /*-----------------------------------*/ /*--- Print out the certificates. ---*/ /*-----------------------------------*/ void show_certs(SSL* ssl) { X509 *cert; char *line; char *cipher; int index = 0; cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ if (cert != NULL) { printf("Server certificates:\n"); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("Subject: %s\n", line); free(line); /* free the malloc'ed string */ line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("Issuer: %s\n", line); free(line); /* free the malloc'ed string */ X509_free(cert); /* free the malloc'ed certificate copy */ } else printf("No certificates.\n"); do { cipher = (char*)SSL_get_cipher_list(ssl, index); if (cipher) { printf("Cipher = %s\n", cipher); index++; } } while (cipher); } void load_certs(SSL_CTX *ctx, char *key, char *cert, char *ca) { SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM); if (!SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Private key doesn't match the cert!\n"); exit(EXIT_FAILURE); } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca)); SSL_CTX_load_verify_locations(ctx, ca, NULL); if (SSL_CTX_get_client_CA_list(ctx) == NULL) { fprintf(stderr, "Could not set client CA list from %s\n", ca); } }