Sunday, November 20, 2011

Getting the certificate in DER and printing it

This hack fetches the certificate from a web server and prints it out in hex format. It's pretty ugly at this point, but note that the certificate bytes match.

#include
#include
#include
#include

BIO *b_err;

int dane_verify(SSL *con, char *s_host, short s_port) {
X509 *dane_peer = NULL;
char buf[BUFSIZ];
if (b_err == NULL)
b_err=BIO_new_fp(stderr,BIO_NOCLOSE);
BIO_printf(b_err, "DANE:%s:%d\n", s_host, s_port);

dane_peer = SSL_get_peer_certificate(con);
if (dane_peer != NULL) {
BIO_printf(b_err, "DANE:Server certificate\n");
X509_NAME_oneline(X509_get_subject_name(dane_peer),
buf,sizeof buf);
BIO_printf(b_err,"DANE:subject=%s\n",buf);
X509_NAME_oneline(X509_get_issuer_name(dane_peer),
buf,sizeof buf);
BIO_printf(b_err,"DANE:issuer=%s\n",buf);
//X509_print(b_err,dane_peer);
int len;
unsigned char *buf, *buf_tmp;

buf = NULL;

len = i2d_X509(dane_peer, &buf);
buf_tmp = buf;
int der_bytes[len+1];
int i;
for (i=0; i BIO_printf(b_err, "%2X", *buf_tmp);
buf_tmp++;
}
BIO_printf(b_err, "\n");
der_bytes[len] = '\0';

BIO_printf(b_err, "DANE: here we go: %X\n", der_bytes);

if (len < 0) {
BIO_printf(b_err, "DANE: ops\n");
} else {
BIO_printf(b_err, "DANE... %d\n", len);
BIO_printf(b_err, "DANE: %u\n", buf);
}



} else
BIO_printf(b_err,"DANE:no peer certificate available\n");

(void)BIO_flush(b_err);
return 0;
}

$ ./openssl s_client -dane -connect www.example.com:443
CONNECTED(00000003)
DANE:www.example.com:443
DANE:no peer certificate available
DANE:www.example.com:443
DANE:no peer certificate available
depth=0 C = US, ST = California, L = Mountain View, O = Default Company Ltd, CN = www.example.com, emailAddress = mathias.samuelson@gmail.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Default Company Ltd, CN = www.example.com, emailAddress = mathias.samuelson@gmail.com
verify return:1
DANE:www.example.com:443
DANE:Server certificate
DANE:subject=/C=US/ST=California/L=Mountain View/O=Default Company Ltd/CN=www.example.com/emailAddress=mathias.samuelson@gmail.com
DANE:issuer=/C=US/ST=California/L=Mountain View/O=Default Company Ltd/CN=www.example.com/emailAddress=mathias.samuelson@gmail.com
3082 2B53082 21E 2 9 087DEC83E4049FDBD30 D 6 92A864886F7 D 1 1 5 5 030819E31 B30 9 6 355 4 613 2555331133011 6 355 4 8 C A43616C69666F726E696131163014 6 355 4 7 C D4D6F756E7461696E2056696577311C301A 6 355 4 A C1344656661756C7420436F6D70616E79204C746431183016 6 355 4 3 C F7777772E6578616D706C652E636F6D312A3028 6 92A864886F7 D 1 9 1161B6D6174686961732E73616D75656C736F6E40676D61696C2E636F6D301E17 D3131313131333232333633395A17 D3132313131323232333633395A30819E31 B30 9 6 355 4 613 2555331133011 6 355 4 8 C A43616C69666F726E696131163014 6 355 4 7 C D4D6F756E7461696E2056696577311C301A 6 355 4 A C1344656661756C7420436F6D70616E79204C746431183016 6 355 4 3 C F7777772E6578616D706C652E636F6D312A3028 6 92A864886F7 D 1 9 1161B6D6174686961732E73616D75656C736F6E40676D61696C2E636F6D30819F30 D 6 92A864886F7 D 1 1 1 5 0 3818D 0308189 28181 0A8148A 27BB0DA5613 5963ABF7092741E443543AA16DEE369ED4E9542298BEF3DFCB16A2D 1C38EC6A89E8CD6 58889BC6E8BBD659F84726AA5E9F2A459BD40 1169AF91479 99CA34747 B75A5D3FC5FE1AF8823D4FC4B 9D7FD92A48244457911B466652E8AC69458E8EA4EA9896A D5AE76A6D 32F5DEB961B24AC61D331 2 3 1 0 130 D 6 92A864886F7 D 1 1 5 5 0 38181 08C2ACCCB27885E42DB35724E3BCE6CD58DA5671CE5AD7B8EC0B5C52421C4AA84BD 3 28D5CFF 19A853DE74ED7 471D3F610489C7FC232522B13623AA4F4B38A 82F28 51016917CE588DA8326156629CF70FFB2663C8A63CE 860CA81E7815F82A4FB3BF7DD385F 38696F5 04254C5BC39451DA220FE24D0578483464F6D58
DANE: here we go: 5FBFE130
DANE... 697
DANE: 3280608
...

The certificate starts with the bytes 0x3082 ... ends with 0x6D58.

We see that the number of bytes is 697, whereas the record in DNS is 699 bytes. The record should have three one octet fields and then the certificate bytes, but I'm actually only seeing two octets before the certificate. Need to look into why that is.

So far so good though.

No comments:

Post a Comment