diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/defines.h | 4 | ||||
-rw-r--r-- | lib/gnutls_dh_primes.c | 2 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 67 | ||||
-rw-r--r-- | lib/strnstr.c | 47 | ||||
-rw-r--r-- | lib/x509/crl.c | 3 | ||||
-rw-r--r-- | lib/x509/pkcs7.c | 3 | ||||
-rw-r--r-- | lib/x509/privkey.c | 2 | ||||
-rw-r--r-- | lib/x509_b64.c | 12 |
11 files changed, 107 insertions, 39 deletions
@@ -9,6 +9,8 @@ Version 0.9.1 - Added ability to generate RSA keys. - Increased the maximum parameter size in order to read some large keys by some CAs. Patch by Ian Peters <itp@ximian.com>. +- Added an strnstr() function and the requirement in some functions to + use null terminated PEM structures is no more. Version 0.9.0 (03/03/2003) - This version is not binary compatible with the previous ones. diff --git a/configure.in b/configure.in index 0d7af4e32a..77b5c6eec0 100644 --- a/configure.in +++ b/configure.in @@ -151,7 +151,7 @@ AC_HEADER_TIME AC_CHECK_HEADERS(unistd.h pwd.h strings.h stdarg.h) AC_CHECK_HEADERS(sys/stat.h sys/types.h sys/socket.h) AC_CHECK_HEADERS(errno.h sys/time.h time.h) -AC_CHECK_FUNCS(bzero memset memmove bcopy memcmp memcpy,,) +AC_CHECK_FUNCS(bzero memset memmove bcopy strnstr memcmp memcpy,,) AC_FUNC_ALLOCA diff --git a/lib/Makefile.am b/lib/Makefile.am index d354c22409..ff45038379 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -41,7 +41,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \ gnutls_str.c gnutls_state.c gnutls_x509.c ext_cert_type.c \ gnutls_rsa_export.c auth_rsa_export.c \ ext_server_name.c auth_dh_common.c \ - dh_compat.c rsa_compat.c + dh_compat.c rsa_compat.c strnstr.c # Separate so we can create the documentation diff --git a/lib/defines.h b/lib/defines.h index 8afb31450f..98f12ad4ee 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -62,6 +62,10 @@ typedef long ptrdiff_t; # include <strings.h> #endif +#ifndef HAVE_STRNSTR +char *strnstr(const char *haystack, const char *needle, size_t haystacklen); +#endif + #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c index 865b93d178..4575c6076c 100644 --- a/lib/gnutls_dh_primes.c +++ b/lib/gnutls_dh_primes.c @@ -227,7 +227,7 @@ int gnutls_dh_params_generate2(gnutls_dh_params params, int bits) * in prime and generator structures. * * If the structure is PEM encoded, it should have a header - * of "BEGIN DH PARAMETERS", and must be null terminated. + * of "BEGIN DH PARAMETERS". * * In case of failure a negative value will be returned, and * 0 on success. diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 5865143fd3..87f008851f 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -307,40 +307,39 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, const static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, const char *input_cert, int input_cert_size) { - int siz, siz2, i; + int size, siz2, i; const char *ptr; opaque *ptr2; gnutls_datum tmp; int ret, count; - if ( (ptr = strstr( input_cert, PEM_PKCS7_SEP)) != NULL) + if ( (ptr = strnstr( input_cert, PEM_PKCS7_SEP, input_cert_size)) != NULL) { - siz = strlen( ptr); + size = strlen( ptr); ret = parse_pkcs7_cert_mem( cert_list, ncerts, ptr, - siz, CERT_PEM); + size, CERT_PEM); return ret; } /* move to the certificate */ - ptr = strstr( input_cert, PEM_CERT_SEP); - if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + ptr = strnstr( input_cert, PEM_CERT_SEP, input_cert_size); + if (ptr == NULL) ptr = strnstr( input_cert, PEM_CERT_SEP2, input_cert_size); if (ptr == NULL) { gnutls_assert(); return GNUTLS_E_BASE64_DECODING_ERROR; } - siz = strlen( ptr); + size = input_cert_size - (ptr - input_cert); i = *ncerts + 1; count = 0; do { - siz2 = _gnutls_fbase64_decode(NULL, ptr, siz, &ptr2); - siz -= siz2; + siz2 = _gnutls_fbase64_decode(NULL, ptr, size, &ptr2); if (siz2 < 0) { gnutls_assert(); @@ -372,8 +371,16 @@ static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, ptr++; /* find the next certificate (if any) */ - ptr = strstr(ptr, PEM_CERT_SEP); - if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + size = input_cert_size - (ptr - input_cert); + + if (size > 0) { + char* ptr2; + + ptr2 = strnstr(ptr, PEM_CERT_SEP, size); + if (ptr2 == NULL) ptr2 = strnstr( ptr, PEM_CERT_SEP2, size); + + ptr = ptr2; + } else ptr = NULL; i++; count++; @@ -863,21 +870,21 @@ int _gnutls_check_key_usage( const gnutls_cert* cert, static int parse_pem_ca_mem( gnutls_x509_crt** cert_list, int* ncerts, const char *input_cert, int input_cert_size) { - int siz, i; + int i, size; const char *ptr; gnutls_datum tmp; int ret, count; /* move to the certificate */ - ptr = strstr( input_cert, PEM_CERT_SEP); - if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + ptr = strnstr( input_cert, PEM_CERT_SEP, input_cert_size); + if (ptr == NULL) ptr = strnstr( input_cert, PEM_CERT_SEP2, input_cert_size); if (ptr == NULL) { gnutls_assert(); return GNUTLS_E_BASE64_DECODING_ERROR; } - siz = strlen( ptr); + size = input_cert_size - (ptr - input_cert); i = *ncerts + 1; count = 0; @@ -901,7 +908,7 @@ static int parse_pem_ca_mem( gnutls_x509_crt** cert_list, int* ncerts, } tmp.data = (char*)ptr; - tmp.size = siz; + tmp.size = size; ret = gnutls_x509_crt_import( @@ -917,8 +924,17 @@ static int parse_pem_ca_mem( gnutls_x509_crt** cert_list, int* ncerts, ptr++; /* find the next certificate (if any) */ - ptr = strstr(ptr, PEM_CERT_SEP); - if (ptr == NULL) ptr = strstr( input_cert, PEM_CERT_SEP2); + + size = input_cert_size - (ptr - input_cert); + + if (size > 0) { + char* ptr2; + + ptr2 = strnstr(ptr, PEM_CERT_SEP, size); + if (ptr2 == NULL) ptr = strnstr( ptr, PEM_CERT_SEP2, size); + + ptr = ptr2; + } else ptr = NULL; i++; count++; @@ -1057,20 +1073,20 @@ int gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials res, static int parse_pem_crl_mem( gnutls_x509_crl** crl_list, int* ncrls, const char *input_crl, int input_crl_size) { - int siz, i; + int size, i; const char *ptr; gnutls_datum tmp; int ret, count; /* move to the certificate */ - ptr = strstr( input_crl, PEM_CRL_SEP); + ptr = strnstr( input_crl, PEM_CRL_SEP, input_crl_size); if (ptr == NULL) { gnutls_assert(); return GNUTLS_E_BASE64_DECODING_ERROR; } - siz = strlen( ptr); + size = input_crl_size - (ptr - input_crl); i = *ncrls + 1; count = 0; @@ -1094,7 +1110,7 @@ static int parse_pem_crl_mem( gnutls_x509_crl** crl_list, int* ncrls, } tmp.data = (char*)ptr; - tmp.size = siz; + tmp.size = size; ret = gnutls_x509_crl_import( @@ -1110,7 +1126,12 @@ static int parse_pem_crl_mem( gnutls_x509_crl** crl_list, int* ncrls, ptr++; /* find the next certificate (if any) */ - ptr = strstr(ptr, PEM_CRL_SEP); + + size = input_crl_size - (ptr - input_crl); + + if (size > 0) + ptr = strnstr(ptr, PEM_CRL_SEP, size); + else ptr = NULL; i++; count++; diff --git a/lib/strnstr.c b/lib/strnstr.c new file mode 100644 index 0000000000..57aed55fb0 --- /dev/null +++ b/lib/strnstr.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2003 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <defines.h> +#ifndef HAVE_STRNSTR +# include <string.h> + +char *strnstr(const char *haystack, const char *needle, size_t haystacklen) +{ + char *p; + ssize_t plen; + ssize_t len = strlen(needle); + + if (*needle == '\0') /* everything matches empty string */ + return (char*) haystack; + + plen = haystacklen; + for (p = (char*) haystack; p != NULL; p = memchr(p + 1, *needle, plen-1)) { + plen = haystacklen - (p - haystack); + + if (plen < len) return NULL; + + if (strncmp(p, needle, len) == 0) + return (p); + } + return NULL; +} + +#endif diff --git a/lib/x509/crl.c b/lib/x509/crl.c index 8d20d57baf..52506b182a 100644 --- a/lib/x509/crl.c +++ b/lib/x509/crl.c @@ -76,8 +76,7 @@ void gnutls_x509_crl_deinit(gnutls_x509_crl crl) * This function will convert the given DER or PEM encoded CRL * to the native gnutls_x509_crl format. The output will be stored in 'crl'. * - * If the CRL is PEM encoded it should have a header of "X509 CRL", and - * it must be a null terminated string. + * If the CRL is PEM encoded it should have a header of "X509 CRL". * * Returns 0 on success. * diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c index ccce9af543..67166ba16f 100644 --- a/lib/x509/pkcs7.c +++ b/lib/x509/pkcs7.c @@ -74,8 +74,7 @@ void gnutls_pkcs7_deinit(gnutls_pkcs7 pkcs7) * This function will convert the given DER or PEM encoded PKCS7 * to the native gnutls_pkcs7 format. The output will be stored in 'pkcs7'. * - * If the PKCS7 is PEM encoded it should have a header of "X509 PKCS7", and - * it must be a null terminated string. + * If the PKCS7 is PEM encoded it should have a header of "X509 PKCS7". * * Returns 0 on success. * diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 1ce006cc80..4cf5b84ac4 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -266,7 +266,7 @@ static ASN1_TYPE decode_dsa_key( const gnutls_datum* raw_key, * to the native gnutls_x509_privkey format. The output will be stored in 'key'. * * If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or - * "CERTIFICATE" and must be a null terminated string. + * "CERTIFICATE". * * Returns 0 on success. * diff --git a/lib/x509_b64.c b/lib/x509_b64.c index 5f3c5dc766..3d8c48d3d3 100644 --- a/lib/x509_b64.c +++ b/lib/x509_b64.c @@ -395,9 +395,9 @@ int _gnutls_fbase64_decode( const opaque* header, const opaque * data, size_t da } strcpy( pem_header, top); strcpy( pem_header, header); - rdata = strstr( data, pem_header); + rdata = strnstr( data, pem_header, data_size); } else { - rdata = strstr( data, top); + rdata = strnstr( data, top, data_size); } if (rdata==NULL) { @@ -412,7 +412,7 @@ int _gnutls_fbase64_decode( const opaque* header, const opaque * data, size_t da return GNUTLS_E_BASE64_DECODING_ERROR; } - kdata = strstr( rdata, ENDSTR); + kdata = strnstr( rdata, ENDSTR, data_size); if (kdata==NULL) { gnutls_assert(); return GNUTLS_E_BASE64_DECODING_ERROR; @@ -424,7 +424,7 @@ int _gnutls_fbase64_decode( const opaque* header, const opaque * data, size_t da /* position is now after the ---BEGIN--- headers */ - kdata = strstr( rdata, bottom); + kdata = strnstr( rdata, bottom, data_size); if (kdata==NULL) { gnutls_assert(); return GNUTLS_E_BASE64_DECODING_ERROR; @@ -467,8 +467,6 @@ int _gnutls_fbase64_decode( const opaque* header, const opaque * data, size_t da * is non null this function will search for "-----BEGIN header" and decode * only this part. Otherwise it will decode the first PEM packet found. * - * Note that b64_data should be null terminated. - * * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not long enough, * or 0 on success. **/ @@ -509,8 +507,6 @@ int size; * You should use the function gnutls_free() to * free the returned data. * - * Note that b64_data should be null terminated. - * **/ int gnutls_pem_base64_decode_alloc( const char* header, const gnutls_datum *b64_data, gnutls_datum* result) |