1662
static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
1666
if((ilen = (int)len) < 0)
1667
return 1; /* buffer too big */
1669
i = i2t_ASN1_OBJECT(buf, ilen, a);
1672
return 1; /* buffer too small */
1677
static CURLcode push_certinfo_len(struct SessionHandle *data,
1683
struct curl_certinfo *ci = &data->info.certs;
1685
struct curl_slist *nl;
1686
CURLcode res = CURLE_OK;
1687
size_t labellen = strlen(label);
1688
size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
1690
outp = malloc(outlen);
1692
return CURLE_OUT_OF_MEMORY;
1694
/* sprintf the label and colon */
1695
snprintf(outp, outlen, "%s:", label);
1697
/* memcpy the value (it might not be zero terminated) */
1698
memcpy(&outp[labellen+1], value, valuelen);
1700
/* zero terminate the output */
1701
outp[labellen + 1 + valuelen] = 0;
1703
/* TODO: we should rather introduce an internal API that can do the
1704
equivalent of curl_slist_append but doesn't strdup() the given data as
1705
like in this place the extra malloc/free is totally pointless */
1706
nl = curl_slist_append(ci->certinfo[certnum], outp);
1708
curl_slist_free_all(ci->certinfo[certnum]);
1709
res = CURLE_OUT_OF_MEMORY;
1712
ci->certinfo[certnum] = nl;
1719
/* this is a convenience function for push_certinfo_len that takes a zero
1721
static CURLcode push_certinfo(struct SessionHandle *data,
1726
size_t valuelen = strlen(value);
1728
return push_certinfo_len(data, certnum, label, value, valuelen);
1731
static void pubkey_show(struct SessionHandle *data,
1739
size_t left = sizeof(buffer);
1744
snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
1746
for(i=0; i< len; i++) {
1747
snprintf(ptr, left, "%02x:", raw[i]);
1751
infof(data, " %s: %s\n", namebuf, buffer);
1752
push_certinfo(data, num, namebuf, buffer);
1755
#define print_pubkey_BN(_type, _name, _num) \
1757
if (pubkey->pkey._type->_name != NULL) { \
1758
int len = BN_num_bytes(pubkey->pkey._type->_name); \
1759
if(len < (int)sizeof(buf)) { \
1760
BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \
1762
pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \
1767
static int X509V3_ext(struct SessionHandle *data,
1769
STACK_OF(X509_EXTENSION) *exts)
1774
if(sk_X509_EXTENSION_num(exts) <= 0)
1775
/* no extensions, bail out */
1778
for (i=0; i<sk_X509_EXTENSION_num(exts); i++) {
1780
X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1781
BIO *bio_out = BIO_new(BIO_s_mem());
1787
obj = X509_EXTENSION_get_object(ext);
1789
asn1_object_dump(obj, namebuf, sizeof(namebuf));
1791
infof(data, "%s: %s\n", namebuf,
1792
X509_EXTENSION_get_critical(ext)?"(critical)":"");
1794
if(!X509V3_EXT_print(bio_out, ext, 0, 0))
1795
M_ASN1_OCTET_STRING_print(bio_out, ext->value);
1797
BIO_get_mem_ptr(bio_out, &biomem);
1799
/* biomem->length bytes at biomem->data, this little loop here is only
1800
done for the infof() call, we send the "raw" data to the certinfo
1802
for(j=0; j<(size_t)biomem->length; j++) {
1804
if(biomem->data[j] == '\n') {
1806
j++; /* skip the newline */
1808
while((biomem->data[j] == ' ') && (j<(size_t)biomem->length))
1810
if(j<(size_t)biomem->length)
1811
ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, biomem->data[j]);
1813
infof(data, " %s\n", buf);
1815
push_certinfo(data, certnum, namebuf, buf);
1820
return 0; /* all is fine */
1824
static void X509_signature(struct SessionHandle *data,
1831
for (i=0; i<sig->length; i++)
1832
ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
1834
infof(data, " Signature: %s\n", buf);
1835
push_certinfo(data, numcert, "Signature", buf);
1838
static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
1840
BIO *bio_out = BIO_new(BIO_s_mem());
1843
/* this outputs the cert in this 64 column wide style with newlines and
1844
-----BEGIN CERTIFICATE----- texts and more */
1845
PEM_write_bio_X509(bio_out, x);
1847
BIO_get_mem_ptr(bio_out, &biomem);
1849
infof(data, "%s\n", biomem->data);
1851
push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length);
1858
static int init_certinfo(struct SessionHandle *data,
1861
struct curl_certinfo *ci = &data->info.certs;
1862
struct curl_slist **table;
1864
Curl_ssl_free_certinfo(data);
1866
ci->num_of_certs = num;
1867
table = calloc(sizeof(struct curl_slist *) * num, 1);
1871
ci->certinfo = table;
1875
static CURLcode get_cert_chain(struct connectdata *conn,
1876
struct ssl_connect_data *connssl)
1882
struct SessionHandle *data = conn->data;
1885
sk = SSL_get_peer_cert_chain(connssl->handle);
1888
return CURLE_OUT_OF_MEMORY;
1890
numcerts = sk_X509_num(sk);
1892
if(init_certinfo(data, numcerts))
1893
return CURLE_OUT_OF_MEMORY;
1895
infof(data, "--- Certificate chain\n");
1896
for (i=0; i<numcerts; i++) {
1899
ASN1_TIME *certdate;
1901
/* get the certs in "importance order" */
1903
X509 *x = sk_X509_value(sk, numcerts - i - 1);
1905
X509 *x = sk_X509_value(sk, i);
1909
EVP_PKEY *pubkey=NULL;
1913
(void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf));
1914
infof(data, "%2d Subject: %s\n",i,buf);
1915
push_certinfo(data, i, "Subject", buf);
1917
(void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
1918
infof(data, " Issuer: %s\n",buf);
1919
push_certinfo(data, i, "Issuer", buf);
1921
value = X509_get_version(x);
1922
infof(data, " Version: %lu (0x%lx)\n", value+1, value);
1923
snprintf(buf, sizeof(buf), "%lx", value);
1924
push_certinfo(data, i, "Version", buf); /* hex */
1926
num=X509_get_serialNumber(x);
1927
if (num->length <= 4) {
1928
value = ASN1_INTEGER_get(num);
1929
infof(data," Serial Number: %ld (0x%lx)\n", value, value);
1930
snprintf(buf, sizeof(buf), "%lx", value);
1936
if(num->type == V_ASN1_NEG_INTEGER)
1939
for (j=0; j<num->length; j++) {
1940
/* TODO: length restrictions */
1941
snprintf(ptr, 3, "%02x%c",num->data[j],
1942
((j+1 == num->length)?'\n':':'));
1946
infof(data," Serial Number: %s\n", buf);
1951
push_certinfo(data, i, "Serial Number", buf); /* hex */
1953
cinf = x->cert_info;
1955
j = asn1_object_dump(cinf->signature->algorithm, buf, sizeof(buf));
1957
infof(data, " Signature Algorithm: %s\n", buf);
1958
push_certinfo(data, i, "Signature Algorithm", buf);
1961
certdate = X509_get_notBefore(x);
1962
asn1_output(certdate, buf, sizeof(buf));
1963
infof(data, " Start date: %s\n", buf);
1964
push_certinfo(data, i, "Start date", buf);
1966
certdate = X509_get_notAfter(x);
1967
asn1_output(certdate, buf, sizeof(buf));
1968
infof(data, " Expire date: %s\n", buf);
1969
push_certinfo(data, i, "Expire date", buf);
1971
j = asn1_object_dump(cinf->key->algor->algorithm, buf, sizeof(buf));
1973
infof(data, " Public Key Algorithm: %s\n", buf);
1974
push_certinfo(data, i, "Public Key Algorithm", buf);
1977
pubkey = X509_get_pubkey(x);
1979
infof(data, " Unable to load public key\n");
1981
switch(pubkey->type) {
1983
infof(data, " RSA Public Key (%d bits)\n",
1984
BN_num_bits(pubkey->pkey.rsa->n));
1985
snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n));
1986
push_certinfo(data, i, "RSA Public Key", buf);
1988
print_pubkey_BN(rsa, n, i);
1989
print_pubkey_BN(rsa, e, i);
1990
print_pubkey_BN(rsa, d, i);
1991
print_pubkey_BN(rsa, p, i);
1992
print_pubkey_BN(rsa, q, i);
1993
print_pubkey_BN(rsa, dmp1, i);
1994
print_pubkey_BN(rsa, dmq1, i);
1995
print_pubkey_BN(rsa, iqmp, i);
1998
print_pubkey_BN(dsa, p, i);
1999
print_pubkey_BN(dsa, q, i);
2000
print_pubkey_BN(dsa, g, i);
2001
print_pubkey_BN(dsa, priv_key, i);
2002
print_pubkey_BN(dsa, pub_key, i);
2005
print_pubkey_BN(dh, p, i);
2006
print_pubkey_BN(dh, g, i);
2007
print_pubkey_BN(dh, priv_key, i);
2008
print_pubkey_BN(dh, pub_key, i);
2011
case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
2018
X509V3_ext(data, i, cinf->extensions);
2020
X509_signature(data, i, x->signature);
2022
dumpcert(data, x, i);
1590
2029
* Get the server cert, verify it and show it etc, only call failf() if the
1591
2030
* 'strict' argument is TRUE as otherwise all this is for informational
1641
str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert),
2091
rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
2092
buffer, sizeof(buffer));
1645
2095
failf(data, "SSL: couldn't get X509-issuer name!");
1646
2096
retcode = CURLE_SSL_CONNECT_ERROR;
1649
infof(data, "\t issuer: %s\n", str);
2099
infof(data, "\t issuer: %s\n", buffer);
1652
2101
/* We could do all sorts of certificate verification stuff here before
1653
2102
deallocating the certificate. */
2104
/* e.g. match issuer name with provided issuer certificate */
2105
if (data->set.str[STRING_SSL_ISSUERCERT]) {
2106
if (! (fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r"))) {
2108
failf(data, "SSL: Unable to open issuer cert (%s)\n",
2109
data->set.str[STRING_SSL_ISSUERCERT]);
2110
X509_free(connssl->server_cert);
2111
connssl->server_cert = NULL;
2112
return CURLE_SSL_ISSUER_ERROR;
2114
issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
2117
failf(data, "SSL: Unable to read issuer cert (%s)\n",
2118
data->set.str[STRING_SSL_ISSUERCERT]);
2119
X509_free(connssl->server_cert);
2122
return CURLE_SSL_ISSUER_ERROR;
2125
if (X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
2127
failf(data, "SSL: Certificate issuer check failed (%s)\n",
2128
data->set.str[STRING_SSL_ISSUERCERT]);
2129
X509_free(connssl->server_cert);
2131
connssl->server_cert = NULL;
2132
return CURLE_SSL_ISSUER_ERROR;
2134
infof(data, "\t SSL certificate issuer check ok (%s)\n",
2135
data->set.str[STRING_SSL_ISSUERCERT]);
1655
2139
lerr = data->set.ssl.certverifyresult=
1656
2140
SSL_get_verify_result(connssl->handle);
1657
2141
if(data->set.ssl.certverifyresult != X509_V_OK) {
1658
2142
if(data->set.ssl.verifypeer) {
1659
2143
/* We probably never reach this, because SSL_connect() will fail
1660
and we return earlyer if verifypeer is set? */
2144
and we return earlier if verifypeer is set? */
1662
2146
failf(data, "SSL certificate verify result: %s (%ld)",
1663
2147
X509_verify_cert_error_string(lerr), lerr);
1664
2148
retcode = CURLE_PEER_FAILED_VERIFICATION;
1667
infof(data, "SSL certificate verify result: %s (%ld),"
2151
infof(data, "\t SSL certificate verify result: %s (%ld),"
1668
2152
" continuing anyway.\n",
1669
2153
X509_verify_cert_error_string(lerr), lerr);
1672
infof(data, "SSL certificate verify ok.\n");
2156
infof(data, "\t SSL certificate verify ok.\n");
1675
2159
X509_free(connssl->server_cert);