}
/* returns non-zero on failure */
-static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
+static CURLcode x509_name_oneline(X509_NAME *a, struct dynbuf *d)
{
BIO *bio_out = BIO_new(BIO_s_mem());
BUF_MEM *biomem;
int rc;
-
- if(!bio_out)
- return 1; /* alloc failed! */
-
- rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
- BIO_get_mem_ptr(bio_out, &biomem);
-
- if((size_t)biomem->length < size)
- size = biomem->length;
- else
- size--; /* do not overwrite the buffer end */
-
- memcpy(buf, biomem->data, size);
- buf[size] = 0;
-
- BIO_free(bio_out);
-
- return !rc;
+ CURLcode result = CURLE_OUT_OF_MEMORY;
+
+ if(bio_out) {
+ Curl_dyn_reset(d);
+ rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
+ if(rc != -1) {
+ BIO_get_mem_ptr(bio_out, &biomem);
+ result = Curl_dyn_addn(d, biomem->data, biomem->length);
+ BIO_free(bio_out);
+ }
+ }
+ return result;
}
/**
/* we have to look to the last occurrence of a commonName in the
distinguished one to get the most significant one. */
int i = -1;
- unsigned char *peer_CN = NULL;
- int peerlen = 0;
+ unsigned char *cn = NULL;
+ int cnlen = 0;
+ bool free_cn = FALSE;
/* The following is done because of a bug in 0.9.6b */
X509_NAME *name = X509_get_subject_name(server_cert);
conditional in the future when OpenSSL has been fixed. */
if(tmp) {
if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
- peerlen = ASN1_STRING_length(tmp);
- if(peerlen >= 0) {
- peer_CN = OPENSSL_malloc(peerlen + 1);
- if(peer_CN) {
- memcpy(peer_CN, ASN1_STRING_get0_data(tmp), peerlen);
- peer_CN[peerlen] = '\0';
- }
- else
- result = CURLE_OUT_OF_MEMORY;
- }
+ cnlen = ASN1_STRING_length(tmp);
+ cn = (unsigned char *) ASN1_STRING_get0_data(tmp);
+ }
+ else { /* not a UTF8 name */
+ cnlen = ASN1_STRING_to_UTF8(&cn, tmp);
+ free_cn = TRUE;
}
- else /* not a UTF8 name */
- peerlen = ASN1_STRING_to_UTF8(&peer_CN, tmp);
- if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != peerlen)) {
+ if((cnlen <= 0) || !cn)
+ result = CURLE_OUT_OF_MEMORY;
+ else if((size_t)cnlen != strlen((char *)cn)) {
/* there was a terminating zero before the end of string, this
cannot match and we return failure! */
failf(data, "SSL: illegal cert name field");
if(result)
/* error already detected, pass through */
;
- else if(!peer_CN) {
+ else if(!cn) {
failf(data,
"SSL: unable to obtain common name from peer certificate");
result = CURLE_PEER_FAILED_VERIFICATION;
}
- else if(!Curl_cert_hostcheck((const char *)peer_CN,
- peerlen, peer->hostname, hostlen)) {
+ else if(!Curl_cert_hostcheck((const char *)cn, cnlen,
+ peer->hostname, hostlen)) {
failf(data, "SSL: certificate subject name '%s' does not match "
- "target hostname '%s'", peer_CN, peer->dispname);
+ "target hostname '%s'", cn, peer->dispname);
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
- infof(data, " common name: %s (matched)", peer_CN);
+ infof(data, " common name: %s (matched)", cn);
}
- if(peer_CN)
- OPENSSL_free(peer_CN);
+ if(free_cn)
+ OPENSSL_free(cn);
}
return result;
#define infof_certstack(data, ssl)
#endif
+#define MAX_CERT_NAME_LENGTH 2048
+
CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ossl_ctx *octx,
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
CURLcode result = CURLE_OK;
- int rc;
long lerr;
X509 *issuer;
BIO *fp = NULL;
char error_buffer[256]="";
- char buffer[2048];
const char *ptr;
BIO *mem = BIO_new(BIO_s_mem());
bool strict = (conn_config->verifypeer || conn_config->verifyhost);
+ struct dynbuf dname;
DEBUGASSERT(octx);
+ Curl_dyn_init(&dname, MAX_CERT_NAME_LENGTH);
+
if(!mem) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
infof(data, "%s certificate:",
Curl_ssl_cf_is_proxy(cf) ? "Proxy" : "Server");
- rc = x509_name_oneline(X509_get_subject_name(octx->server_cert),
- buffer, sizeof(buffer));
- infof(data, " subject: %s", rc ? "[NONE]" : buffer);
+ result = x509_name_oneline(X509_get_subject_name(octx->server_cert),
+ &dname);
+ infof(data, " subject: %s", result ? "[NONE]" : Curl_dyn_ptr(&dname));
#ifndef CURL_DISABLE_VERBOSE_STRINGS
{
if(result) {
X509_free(octx->server_cert);
octx->server_cert = NULL;
+ Curl_dyn_free(&dname);
return result;
}
}
- rc = x509_name_oneline(X509_get_issuer_name(octx->server_cert),
- buffer, sizeof(buffer));
- if(rc) {
+ result = x509_name_oneline(X509_get_issuer_name(octx->server_cert),
+ &dname);
+ if(result) {
if(strict)
failf(data, "SSL: could not get X509-issuer name");
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
- infof(data, " issuer: %s", buffer);
+ infof(data, " issuer: %s", Curl_dyn_ptr(&dname));
+ Curl_dyn_free(&dname);
/* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */
else
infof(data, " SSL certificate verify ok.");
}
-
infof_certstack(data, octx->ssl);
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \