21 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
27 #include <openssl/rand.h>
28 #include <openssl/ssl.h>
29 #include <openssl/err.h>
30 #include <sys/select.h>
34 #define CAPATH "/etc/ssl/certs"
36 #define BUFFERSIZE 16384
38 #define STRBUFFERSIZE 256
40 #define USERAGENT "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0"
86 char*
join(
char* buffer,
const char* origin,
size_t *from,
size_t size);
195 char *
time_t_to_str(
char *buffer,
size_t bufsize,
const char* format, time_t *tim);
206 void print_time(ASN1_TIME* asn1time,
char* pre_string,
char* dateformat);
225 void panic(
char *msg);
227 int main(
int argc,
char *argv[])
231 char *server = argv[1];
233 char *httpquerytemplate =
"GET / HTTP/1.1" CRLF "Host: %s" CRLF "User-Agent: %s" CRLF CRLF;
234 char httpquery[1024];
237 sprintf (httpquery, httpquerytemplate, server,
USERAGENT);
243 port = atoi (argv[2]);
248 panic (
"Couldn't connect host");
251 panic (
"Couldn't stablish secure connection");
254 panic (
"Couldn't send anything to the server");
259 panic (
"Couldn't receive the message");
261 printf (
"Received %lu bytes\n", strlen(response));
268 char*
join(
char* buffer,
const char* origin,
size_t *from,
size_t size)
273 buffer[i++] = origin[(*from)++];
281 const char* data = (
char*)time->data;
286 memset(&t, 0,
sizeof(t));
287 size_t datalen = strlen(data);
289 if (time->type == V_ASN1_UTCTIME) {
293 t.tm_year = atoi (
join(buf, data, &p, 2));
296 datalen = strlen(data+2);
297 }
else if (time->type == V_ASN1_GENERALIZEDTIME) {
302 t.tm_year = atoi (
join(buf, data, &p, 4));
304 datalen = strlen(data+4);
309 t.tm_mon = atoi (
join(buf, data, &p, 2))-1;
310 t.tm_mday= atoi (
join(buf, data, &p, 2));
311 t.tm_hour= atoi (
join(buf, data, &p, 2));
314 return !(*tmt = mktime(&t));
315 t.tm_min = atoi (
join(buf, data, &p, 2));
318 return !(*tmt = mktime(&t));
319 t.tm_sec = atoi (
join(buf, data, &p, 2));
322 return !(*tmt = mktime(&t));
329 ctx = X509_STORE_CTX_new();
330 X509_STORE *store = X509_STORE_new();
331 X509_STORE_load_locations(store, NULL,
CAPATH);
332 X509_STORE_add_cert(store, certificate);
334 X509_STORE_CTX_init(ctx, store, certificate, NULL);
336 status = X509_verify_cert(ctx);
344 struct hostent *host = gethostbyname (server);
345 struct sockaddr_in addr;
350 h->
skt = socket (AF_INET, SOCK_STREAM, 0);
358 addr.sin_family = AF_INET;
359 addr.sin_port = htons (port);
360 addr.sin_addr = *((
struct in_addr *) host->h_addr);
361 bzero (&(addr.sin_zero), 8);
364 h->
err = connect (h->
skt, (
struct sockaddr *) &addr, sizeof (
struct sockaddr));
376 SSL_load_error_strings();
380 h->
ctx = SSL_CTX_new(SSLv23_client_method());
387 h->
ssl = SSL_new (h->
ctx);
391 if (SSL_set_fd(h->
ssl, h->
skt) == 0)
394 if (SSL_CTX_load_verify_locations(h->
ctx, NULL,
CAPATH) == 0)
399 printf (
"VDepth: %d\n", SSL_get_verify_depth(h->
ssl));
401 if (SSL_connect (h->
ssl) < 1)
410 int bytes = SSL_write(h->
ssl, msg, strlen(msg));
421 FD_SET(h->
skt, &fds);
426 tv.tv_sec = (int)(timeout);
427 tv.tv_usec = (int)((timeout - (
int)(timeout)) * 1000000.0);
429 int ret = select(h->
skt+1, rset, wset, NULL, &tv);
435 size_t bytes, totalbytes = 0;
452 bytes = SSL_read (h->
ssl, buffer, BUFFERSIZE -1);
453 buffer[bytes] =
'\0';
458 if (totalbytes + bytes > allocated)
461 *data = realloc(*data, allocated *
sizeof(
char));
463 strcat(*data, buffer);
471 long vresult = SSL_get_verify_result (h->
ssl);
473 STACK_OF(X509) *chain;
476 printf (
"Verify result: %ld (%s)\n", vresult, X509_verify_cert_error_string(vresult));
477 printf (
"Verify mode: %d\n", SSL_get_verify_mode(h->
ssl));
478 printf (
"SSL version: %s\n", SSL_get_version(h->
ssl));
479 printf (
"Cipher name : %s\n", SSL_get_cipher_name(h->
ssl));
480 printf (
"Cipher version: %s\n", SSL_get_cipher_version(h->
ssl));
482 printf (
"--------------------------------------------\n");
483 printf (
"Certificate:\n");
484 cert = SSL_get_peer_certificate(h->
ssl);
491 fprintf(stderr,
"------ ERROR: Peer certificate not present!!\n");
493 printf (
"--------------------------------------------\n");
494 printf (
"The entire certificate chain: \n");
495 chain = SSL_get_peer_cert_chain(h->
ssl);
498 printf (
"Certificates on chain: %d\n", sk_X509_num(chain));
499 for (i=0; i<sk_X509_num(chain); i++)
501 cert = sk_X509_value(chain, i);
508 printf (
" ·················\n");
513 fprintf (stderr,
"------- ERROR: Couldn't get certificate chain!!\n");
519 X509_NAME_ENTRY* entry;
524 certname = X509_get_subject_name(cert);
525 for (i=0; i< X509_NAME_entry_count(certname); i++)
527 entry = X509_NAME_get_entry(certname, i);
532 int n = OBJ_obj2nid(entry->object);
533 if ((n == NID_undef) || ((s = (
char*)OBJ_nid2sn(n)) == NULL))
535 i2t_ASN1_OBJECT(buffer,
sizeof(buffer), entry->object);
538 printf (
"%s = %s\n", s, entry->value->data);
541 print_time(X509_get_notBefore(cert),
"Not Before",
"%d/%m/%Y %H:%M:%S");
542 print_time(X509_get_notAfter(cert),
"Not After",
"%d/%m/%Y %H:%M:%S");
549 char *
time_t_to_str(
char *buffer,
size_t bufsize,
const char* format, time_t *tim)
553 strftime(buffer, bufsize, format, &_tm);
557 void print_time(ASN1_TIME* asn1time,
char* pre_string,
char* dateformat)
565 printf (
"%s: (error)\n", pre_string);
573 SSL_CIPHER_description(cipher, tmp, STRBUFFERSIZE);
580 fprintf(stderr,
"You must specify a web server to connect through HTTPS and additionally a port:\n");
581 fprintf(stderr,
" %s server [port]\n", executable);
582 fprintf(stderr,
"------------\n\n");
588 fprintf (stderr,
"Error: %s (errno %d, %s)\n", msg, errno, strerror(errno));
590 ERR_print_errors_fp(stderr);
int SSL_send(Sslc *h, char *msg)
int ASN1_TIME_to_time_t(ASN1_TIME *time, time_t *tmt)
char * join(char *buffer, const char *origin, size_t *from, size_t size)
void SSL_print_info(Sslc *h)
void print_usage(char *executable)
int SSL_Connection(Sslc *h)
int TCP_select(Sslc *h, double timeout)
int TCP_Connection(Sslc *h, char *server, int port)
void print_time(ASN1_TIME *asn1time, char *pre_string, char *dateformat)
long int check_certificate_validity(X509 *certificate)
char * SSL_cipher_description(SSL_CIPHER *cipher)
int SSL_recv(Sslc *h, char **data)
void SSL_print_certificate_info(X509 *cert)
char * time_t_to_str(char *buffer, size_t bufsize, const char *format, time_t *tim)