use null terminated PEM structures is no more.
- 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.
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
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
# 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
* 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.
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();
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++;
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;
}
tmp.data = (char*)ptr;
- tmp.size = siz;
+ tmp.size = size;
ret =
gnutls_x509_crt_import(
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++;
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;
}
tmp.data = (char*)ptr;
- tmp.size = siz;
+ tmp.size = size;
ret =
gnutls_x509_crl_import(
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++;
--- /dev/null
+/*
+ * 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
* 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.
*
* 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.
*
* 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.
*
}
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) {
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;
/* 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;
* 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.
**/
* 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)