mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
darwinssl: handle long strings in TLS certs
... as the previous fixed length 128 bytes buffer was sometimes too small. Fixes #1823 Closes #1831 Reported-by: Benjamin Sergeant Assisted-by: Bill Pyne, Ray Satiro, Nick Zitzmann
This commit is contained in:
parent
8a84fcc4b5
commit
b3b75d1778
@ -849,7 +849,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
|
|||||||
into a string. Some aren't available under iOS or newer cats. So here's
|
into a string. Some aren't available under iOS or newer cats. So here's
|
||||||
a unified function for getting a string describing the certificate that
|
a unified function for getting a string describing the certificate that
|
||||||
ought to work in all cats starting with Leopard. */
|
ought to work in all cats starting with Leopard. */
|
||||||
CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
|
CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
|
||||||
{
|
{
|
||||||
CFStringRef server_cert_summary = CFSTR("(null)");
|
CFStringRef server_cert_summary = CFSTR("(null)");
|
||||||
|
|
||||||
@ -876,6 +876,39 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
|
|||||||
return server_cert_summary;
|
return server_cert_summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode CopyCertSubject(struct Curl_easy *data,
|
||||||
|
SecCertificateRef cert, char **certp)
|
||||||
|
{
|
||||||
|
CFStringRef c = getsubject(cert);
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
char *cbuf = NULL;
|
||||||
|
*certp = NULL;
|
||||||
|
|
||||||
|
/* If subject is not UTF-8 then check if it can be converted */
|
||||||
|
if(!CFStringGetCStringPtr(c, kCFStringEncodingUTF8)) {
|
||||||
|
size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
|
||||||
|
cbuf = calloc(cbuf_size, 1);
|
||||||
|
if(cbuf) {
|
||||||
|
if(!CFStringGetCString(c, cbuf, cbuf_size,
|
||||||
|
kCFStringEncodingUTF8)) {
|
||||||
|
failf(data, "SSL: invalid CA certificate subject");
|
||||||
|
result = CURLE_SSL_CACERT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* pass back the buffer */
|
||||||
|
*certp = cbuf;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(result)
|
||||||
|
free(cbuf);
|
||||||
|
CFRelease(c);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#if CURL_SUPPORT_MAC_10_6
|
#if CURL_SUPPORT_MAC_10_6
|
||||||
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
|
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
|
||||||
deprecation warnings, so let's not compile this unless it's necessary: */
|
deprecation warnings, so let's not compile this unless it's necessary: */
|
||||||
@ -1418,20 +1451,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
/* If we found one, print it out: */
|
/* If we found one, print it out: */
|
||||||
err = SecIdentityCopyCertificate(cert_and_key, &cert);
|
err = SecIdentityCopyCertificate(cert_and_key, &cert);
|
||||||
if(err == noErr) {
|
if(err == noErr) {
|
||||||
CFStringRef cert_summary = CopyCertSubject(cert);
|
char *certp;
|
||||||
char cert_summary_c[128];
|
CURLcode result = CopyCertSubject(data, cert, &certp);
|
||||||
|
if(!result) {
|
||||||
|
infof(data, "Client certificate: %s\n", certp);
|
||||||
|
free(certp);
|
||||||
|
}
|
||||||
|
|
||||||
if(cert_summary) {
|
|
||||||
memset(cert_summary_c, 0, 128);
|
|
||||||
if(CFStringGetCString(cert_summary,
|
|
||||||
cert_summary_c,
|
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
infof(data, "Client certificate: %s\n", cert_summary_c);
|
|
||||||
}
|
|
||||||
CFRelease(cert_summary);
|
|
||||||
CFRelease(cert);
|
CFRelease(cert);
|
||||||
}
|
if(result)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
certs_c[0] = cert_and_key;
|
certs_c[0] = cert_and_key;
|
||||||
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
|
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
|
||||||
@ -1875,6 +1904,8 @@ static int append_cert_to_array(struct Curl_easy *data,
|
|||||||
CFMutableArrayRef array)
|
CFMutableArrayRef array)
|
||||||
{
|
{
|
||||||
CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
|
CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
|
||||||
|
char *certp;
|
||||||
|
CURLcode result;
|
||||||
if(!certdata) {
|
if(!certdata) {
|
||||||
failf(data, "SSL: failed to allocate array for CA certificate");
|
failf(data, "SSL: failed to allocate array for CA certificate");
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@ -1889,25 +1920,10 @@ static int append_cert_to_array(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if cacert is valid. */
|
/* Check if cacert is valid. */
|
||||||
CFStringRef subject = CopyCertSubject(cacert);
|
result = CopyCertSubject(data, cacert, &certp);
|
||||||
if(subject) {
|
if(result)
|
||||||
char subject_cbuf[128];
|
return result;
|
||||||
memset(subject_cbuf, 0, 128);
|
free(certp);
|
||||||
if(!CFStringGetCString(subject,
|
|
||||||
subject_cbuf,
|
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
CFRelease(cacert);
|
|
||||||
failf(data, "SSL: invalid CA certificate subject");
|
|
||||||
return CURLE_SSL_CACERT;
|
|
||||||
}
|
|
||||||
CFRelease(subject);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CFRelease(cacert);
|
|
||||||
failf(data, "SSL: invalid CA certificate");
|
|
||||||
return CURLE_SSL_CACERT;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFArrayAppendValue(array, cacert);
|
CFArrayAppendValue(array, cacert);
|
||||||
CFRelease(cacert);
|
CFRelease(cacert);
|
||||||
@ -2299,8 +2315,6 @@ show_verbose_server_cert(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
CFStringRef server_cert_summary;
|
|
||||||
char server_cert_summary_c[128];
|
|
||||||
CFArrayRef server_certs = NULL;
|
CFArrayRef server_certs = NULL;
|
||||||
SecCertificateRef server_cert;
|
SecCertificateRef server_cert;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
@ -2319,16 +2333,14 @@ show_verbose_server_cert(struct connectdata *conn,
|
|||||||
if(err == noErr && trust) {
|
if(err == noErr && trust) {
|
||||||
count = SecTrustGetCertificateCount(trust);
|
count = SecTrustGetCertificateCount(trust);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
|
CURLcode result;
|
||||||
|
char *certp;
|
||||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||||
server_cert_summary = CopyCertSubject(server_cert);
|
result = CopyCertSubject(data, server_cert, &certp);
|
||||||
memset(server_cert_summary_c, 0, 128);
|
if(!result) {
|
||||||
if(CFStringGetCString(server_cert_summary,
|
infof(data, "Server certificate: %s\n", certp);
|
||||||
server_cert_summary_c,
|
free(certp);
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_cert_summary);
|
|
||||||
}
|
}
|
||||||
CFRelease(trust);
|
CFRelease(trust);
|
||||||
}
|
}
|
||||||
@ -2347,16 +2359,14 @@ show_verbose_server_cert(struct connectdata *conn,
|
|||||||
if(err == noErr && trust) {
|
if(err == noErr && trust) {
|
||||||
count = SecTrustGetCertificateCount(trust);
|
count = SecTrustGetCertificateCount(trust);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
|
char *certp;
|
||||||
|
CURLcode result;
|
||||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||||
server_cert_summary = CopyCertSubject(server_cert);
|
result = CopyCertSubject(data, server_cert, &certp);
|
||||||
memset(server_cert_summary_c, 0, 128);
|
if(!result) {
|
||||||
if(CFStringGetCString(server_cert_summary,
|
infof(data, "Server certificate: %s\n", certp);
|
||||||
server_cert_summary_c,
|
free(certp);
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_cert_summary);
|
|
||||||
}
|
}
|
||||||
CFRelease(trust);
|
CFRelease(trust);
|
||||||
}
|
}
|
||||||
@ -2368,18 +2378,15 @@ show_verbose_server_cert(struct connectdata *conn,
|
|||||||
if(err == noErr && server_certs) {
|
if(err == noErr && server_certs) {
|
||||||
count = CFArrayGetCount(server_certs);
|
count = CFArrayGetCount(server_certs);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
|
char *certp;
|
||||||
|
CURLcode result;
|
||||||
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
|
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
|
||||||
i);
|
i);
|
||||||
|
result = CopyCertSubject(data, server_cert, &certp);
|
||||||
server_cert_summary = CopyCertSubject(server_cert);
|
if(!result) {
|
||||||
memset(server_cert_summary_c, 0, 128);
|
infof(data, "Server certificate: %s\n", certp);
|
||||||
if(CFStringGetCString(server_cert_summary,
|
free(certp);
|
||||||
server_cert_summary_c,
|
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_cert_summary);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_certs);
|
CFRelease(server_certs);
|
||||||
}
|
}
|
||||||
@ -2392,16 +2399,14 @@ show_verbose_server_cert(struct connectdata *conn,
|
|||||||
if(err == noErr) {
|
if(err == noErr) {
|
||||||
count = CFArrayGetCount(server_certs);
|
count = CFArrayGetCount(server_certs);
|
||||||
for(i = 0L ; i < count ; i++) {
|
for(i = 0L ; i < count ; i++) {
|
||||||
|
CURLcode result;
|
||||||
|
char *certp;
|
||||||
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
|
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
|
||||||
server_cert_summary = CopyCertSubject(server_cert);
|
result = CopyCertSubject(data, server_cert, &certp);
|
||||||
memset(server_cert_summary_c, 0, 128);
|
if(!result) {
|
||||||
if(CFStringGetCString(server_cert_summary,
|
infof(data, "Server certificate: %s\n", certp);
|
||||||
server_cert_summary_c,
|
free(certp);
|
||||||
128,
|
|
||||||
kCFStringEncodingUTF8)) {
|
|
||||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_cert_summary);
|
|
||||||
}
|
}
|
||||||
CFRelease(server_certs);
|
CFRelease(server_certs);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user