From wcang at yahoo.com Sat Feb 4 03:28:21 2006 From: wcang at yahoo.com (Ang Way Chuang) Date: Sat, 4 Feb 2006 02:28:21 +0000 (GMT) Subject: [Help-gnutls] memory leak in gnutls in multithreaded program?? Message-ID: <20060204022821.4813.qmail@web51502.mail.yahoo.com> Hi all, I wrote a sample server program using gnutls 1.2.9. I did gcry_control(GCRYCTL_SET_THREAD_CBS ...) stuff mentioned in the manual. Yet whenever I create a new thread to service a new session from client, the memory allocation for the server process increases for every new thread created. I saw this behaviour through top.However, when the thread exits, the memory wasn't freed. I run the program under valgrind and there is no memory leak reported. Do I need to do anything special in the thread apart from gnutls_bye, shutdown, close & gnutls_deinit to get the memory freed? Please advise. Thanks Regards, Ang Way Chuang --------------------------------- Yahoo! Cars NEW - sell your car and browse thousands of new and used cars online search now --------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: From jas at extundo.com Thu Feb 9 16:51:12 2006 From: jas at extundo.com (Simon Josefsson) Date: Thu, 09 Feb 2006 16:51:12 +0100 Subject: [Help-gnutls] GnuTLS 1.3.4 - Experimental - Security release Message-ID: This release solves the DER security issue on the experimental branch too. It contains a few other fixes too. GnuTLS is a modern C library that implement the standard network security protocol Transport Layer Security (TLS), for use by network applications. Noteworthy changes since version 1.3.3: - Fix read of out bounds bug in DER parser. Reported by Evgeny Legerov , and debugging help from Protover SSL. Libtasn1 0.2.18 is now required, which contains the previous bug fix. The included libtasn1 version in GnuTLS has been updated. - Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no longer invalidate a session if the underlying send fails, but it will prevent future writes. That is to allow reading the already received data. Patches and bug reports by Yoann Vandoorselaere - Corrected bugs in gnutls_certificate_set_x509_crl() and gnutls_certificate_set_x509_trust(), that caused memory corruption if more than one certificates were added. Report and patch by Max Kellermann. - Fix build problems of OpenCDK on AIX. Thanks to "Heiden, John" . - API and ABI modifications: No changes since last version. Improving GnuTLS is costly, but you can help! We are looking for organizations that find GnuTLS useful and wish to contribute back. You can contribute by reporting bugs, improve the software, or donate money or equipment. Commercial support contracts for GnuTLS are available, and they help finance continued maintenance. Simon Josefsson Datakonsult, a Stockholm based privately held company, is currently funding GnuTLS maintenance. We are always looking for interesting development projects. If you need help to use GnuTLS, or want to help others, you are invited to join our help-gnutls mailing list, see: . The project page of the library is available at: http://www.gnutls.org/ http://www.gnu.org/software/gnutls/ http://josefsson.org/gnutls/ (updated fastest) Here are the compressed sources: http://josefsson.org/gnutls/releases/gnutls-1.3.4.tar.bz2 (3.1MB) ftp://ftp.gnutls.org/pub/gnutls/gnutls-1.3.4.tar.bz2 Here are GPG detached signatures signed using key 0xB565716F: http://josefsson.org/gnutls/releases/gnutls-1.3.4.tar.bz2.sig ftp://ftp.gnutls.org/pub/gnutls/gnutls-1.3.4.tar.bz2.sig The software is cryptographically signed by the author using an OpenPGP key identified by the following information: 1280R/B565716F 2002-05-05 [expires: 2006-02-28] Key fingerprint = 0424 D4EE 81A0 E3D1 19C6 F835 EDA2 1E94 B565 716F The key is available from: http://josefsson.org/key.txt dns:b565716f.josefsson.org?TYPE=CERT Here are the build reports for various platforms: http://josefsson.org/autobuild-logs/gnutls.html Here are the SHA-1 checksums: f412262ab6299f6e4603c3f524551ae0357ff983 gnutls-1.3.4.tar.bz2 3c9ac687440b5e36b4d41eaf15fc6ea98a199a06 gnutls-1.3.4.tar.bz2.sig Enjoy, Nikos and Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 423 bytes Desc: not available URL: From jas at extundo.com Thu Feb 9 16:46:28 2006 From: jas at extundo.com (Simon Josefsson) Date: Thu, 09 Feb 2006 16:46:28 +0100 Subject: [Help-gnutls] GnuTLS 1.2.10 - Security release Message-ID: We are pleased to announce the availability of GnuTLS version 1.2.10, a security bug-fix release on the stable 1.2.x branch. This release fixes several serious bugs that would make the DER decoder in libtasn1 crash on invalid input. The problems were reported by Evgeny Legerov on the 31th of January. We invite more detailed analysis of the problem, following our general security advisory approach explained on: http://www.gnu.org/software/gnutls/security.html Particularly, it would be useful to answer the question of whether these bugs are possible to exploit remotely. It is certainly possible to cause the server to crash. We don't have resources to investigate this problem more ourselves currently. To make it easier for you to review this problem, I have prepared a self test that trigger three bugs in the old libtasn1. It will be part of GnuTLS 1.3.4, in tests/certder.c. A diff between libtasn1 0.2.17 and libtasn1 0.2.18 is also available, for those wishing to analyze the changes made to address the problems. It contains a few unrelated fixes too, but it is not too large. It is available from: http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.2.18-from-0.2.17.patch Please send your analysis to gnutls-dev at gnupg.org and I'll update the security advisory web page pointing to it. GnuTLS is a modern C library that implement the standard network security protocol Transport Layer Security (TLS), for use by network applications. Noteworthy changes since version 1.2.9: - Fix read out bounds bug in DER parser. Reported by Evgeny Legerov , and debugging help from Protover SSL. - Libtasn1 0.2.18 is now required (contains the previous bug fix). The included version has been updated too. - Fix gnutls-cli STARTTLS hang when SIGINT is sent too quickly, thanks to Otto Maddox and Nozomu Ando . - Corrected a bug in certtool for 64 bit machines. Reported by Max Kellermann . - Corrected bugs in gnutls_certificate_set_x509_crl() and gnutls_certificate_set_x509_trust(), that caused memory corruption if more than one certificates were added. Report and patch by Max Kellermann. - Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no longer invalidate a session if the underlying send fails, but it will prevent future writes. That is to allow reading the already received data. Patches and bug reports by Yoann Vandoorselaere Improving GnuTLS is costly, but you can help! We are looking for organizations that find GnuTLS useful and wish to contribute back. You can contribute by reporting bugs, improve the software, or donate money or equipment. Commercial support contracts for GnuTLS are available, and they help finance continued maintenance. Simon Josefsson Datakonsult, a Stockholm based privately held company, is currently funding GnuTLS maintenance. We are always looking for interesting development projects. If you need help to use GnuTLS, or want to help others, you are invited to join our help-gnutls mailing list, see: . The project page of the library is available at: http://www.gnutls.org/ http://www.gnu.org/software/gnutls/ http://josefsson.org/gnutls/ (updated fastest) Here are the compressed sources: http://josefsson.org/gnutls/releases/gnutls-1.2.10.tar.bz2 (2.7MB) ftp://ftp.gnutls.org/pub/gnutls/gnutls-1.2.10.tar.bz2 Here are GPG detached signatures signed using key 0xB565716F: http://josefsson.org/gnutls/releases/gnutls-1.2.10.tar.bz2.sig ftp://ftp.gnutls.org/pub/gnutls/gnutls-1.2.10.tar.bz2.sig The software is cryptographically signed by the author using an OpenPGP key identified by the following information: 1280R/B565716F 2002-05-05 [expires: 2006-02-28] Key fingerprint = 0424 D4EE 81A0 E3D1 19C6 F835 EDA2 1E94 B565 716F The key is available from: http://josefsson.org/key.txt dns:b565716f.josefsson.org?TYPE=CERT Here are the build reports for various platforms: http://josefsson.org/autobuild-logs/gnutls.html Here are the SHA-1 checksums: 18140bebae006e019deb77962836bcd775256aab gnutls-1.2.10.tar.bz2 19d200ce04dc54b55d609a091500d1a2aee6e368 gnutls-1.2.10.tar.bz2.sig Enjoy, Nikos and Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 423 bytes Desc: not available URL: From jas at extundo.com Thu Feb 9 16:38:35 2006 From: jas at extundo.com (Simon Josefsson) Date: Thu, 09 Feb 2006 16:38:35 +0100 Subject: [Help-gnutls] Libtasn1 0.2.18 - Tiny ASN.1 Library - Security release Message-ID: All, this release fixes several serious bugs that would make the DER decoder in libtasn1 crash on invalid input. The problems were reported by Evgeny Legerov on the 31th of January. New releases of GnuTLS will follow later today. We invite more detailed analysis of the problem, following our general security advisory approach explained on: http://www.gnu.org/software/gnutls/security.html Particularly, it would be useful to answer the question of whether these bugs are possible to exploit remotely. It is certainly possible to cause the server to crash. We don't have resources to investigate this problem more ourselves currently. To make it easier for you to review this problem, I have prepared a self test that trigger three bugs in the old libtasn1. It will be part of GnuTLS 1.3.4, in tests/certder.c. I have also created a diff between libtasn1 0.2.17 and libtasn1 0.2.18. I contains unrelated fixes too, but it is not too large. It is available from: http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.2.18-from-0.2.17.patch Please send your analysis to gnutls-dev at gnupg.org and I'll update the security advisory web page pointing to it. Libtasn1 is a standalone library written in C for manipulating ASN.1 objects including DER encoding and DER decoding. It is used by GnuTLS to manipulate X.509 objects and by GNU Shishi to handle Kerberos packets. Version 0.2.18 - Fix out-of-bounds access in DER decoding, reported by Evgeny Legerov. - Add 'const' keyword to some prototypes, thanks to Frediano ZIGLIO. - Fixed typo in src/Makefile.am to make it build with objdir != srcdir, thanks to Bernard Leak. - Update of gnulib files. - Typo fixes in comments, e.g. finish libasn1 to libtasn1 renaming, use LGPL boiler plate on some files in lib/. Commercial support contracts for Libtasn1 are available, and they help finance continued maintenance. Simon Josefsson Datakonsult, a Stockholm based privately held company, is currently funding Libtasn1 maintenance. We are always looking for interesting development projects. If you need help to use Libtasn1, or want to help others, you are invited to join our help-gnutls mailing list, see: . Homepage: http://josefsson.org/libtasn1/ Manual in many formats: http://josefsson.org/gnutls/manual/libtasn1/ Here are the compressed sources: ftp://ftp.gnutls.org/pub/gnutls/libtasn1/libtasn1-0.2.18.tar.gz (888KB) http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.2.18.tar.gz Here are GPG detached signatures using key 0xB565716F: ftp://ftp.gnutls.org/pub/gnutls/libtasn1/libtasn1-0.2.18.tar.gz.sig http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.2.18.tar.gz.sig Here are the SHA-1 checksums: 4f9c1be1586083cd605e17c7948f94deed63b024 libtasn1-0.2.18.tar.gz 08d625e5fbabee2710f9789c8508397e481b048b libtasn1-0.2.18.tar.gz.sig Enjoy, Nikos and Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 423 bytes Desc: not available URL: From jas at extundo.com Fri Feb 10 16:04:24 2006 From: jas at extundo.com (Simon Josefsson) Date: Fri, 10 Feb 2006 16:04:24 +0100 Subject: [Help-gnutls] Re: memory leak in gnutls in multithreaded program?? In-Reply-To: <20060204022821.4813.qmail@web51502.mail.yahoo.com> (Ang Way Chuang's message of "Sat, 4 Feb 2006 02:28:21 +0000 (GMT)") References: <20060204022821.4813.qmail@web51502.mail.yahoo.com> Message-ID: Ang Way Chuang writes: > Hi all, > I wrote a sample server program using gnutls 1.2.9. I did gcry_control > (GCRYCTL_SET_THREAD_CBS ...) stuff mentioned in the manual. Yet whenever I > create a new thread to service a new session from client, the memory allocation > for the server process increases for every new thread created. I saw this > behaviour through top.However, when the thread exits, the memory wasn't freed. > I run the program under valgrind and there is no memory leak reported. Do I > need to do anything special in the thread apart from gnutls_bye, shutdown, > close & gnutls_deinit to get the memory freed? Please advise. Thanks Hi. You'll need to deallocate all other stuff that may have been allocated in that particular thread (like certificates), of course, but other than that. If valgrind doesn't indicate a memory leak, I would guess that the threading sub-system simply steals that memory from you. Sorry that this is little help. Perhaps others have more ideas. Regards, Simon From jas at extundo.com Sat Feb 11 11:36:16 2006 From: jas at extundo.com (Simon Josefsson) Date: Sat, 11 Feb 2006 11:36:16 +0100 Subject: [Help-gnutls] Re: GnuTLS 1.2.10 - Security release In-Reply-To: (Simon Josefsson's message of "Thu, 09 Feb 2006 16:46:28 +0100") References: Message-ID: The patch against GnuTLS 1.2.9 to solve the security problem is below. Actually, it merely fix the calls to the internal libtasn1 APIs that changed with the security fixes for libtasn1. In the future, GnuTLS will not rely on libtasn1 internal functions. We will export _asn1_get_tag_der, _asn1_get_octet_der, _asn1_get_bit_der and _asn1_get_length_der (after removing the leading '_') because these functions have proved useful outside of the library. Note that you'll want to make sure a GnuTLS 1.2.9 built with this patch really uses the new libtasn1, or it will break. Regards, Simon Index: lib/x509/xml.c =================================================================== RCS file: /cvs/gnutls/gnutls/lib/x509/xml.c,v retrieving revision 1.14 retrieving revision 1.14.10.1 diff -u -p -r1.14 -r1.14.10.1 --- lib/x509/xml.c 26 May 2005 15:27:24 -0000 1.14 +++ lib/x509/xml.c 11 Feb 2006 10:28:55 -0000 1.14.10.1 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation + * Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation * * Author: Nikos Mavroyanopoulos * @@ -344,7 +344,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE if (p->type == TYPE_BIT_STRING) { len2 = -1; - len = _asn1_get_length_der(p->value, &len2); + len = _asn1_get_length_der(p->value, p->value_len, &len2); snprintf(tmp, sizeof(tmp), " length=\"%i\"", (len - 1) * 8 - (p->value[len2])); STR_APPEND(tmp); @@ -374,7 +374,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE case TYPE_INTEGER: if (value) { len2 = -1; - len = _asn1_get_length_der(value, &len2); + len = _asn1_get_length_der(value, p->value_len, &len2); for (k = 0; k < len; k++) { snprintf(tmp, sizeof(tmp), @@ -387,7 +387,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE case TYPE_ENUMERATED: if (value) { len2 = -1; - len = _asn1_get_length_der(value, &len2); + len = _asn1_get_length_der(value, p->value_len, &len2); for (k = 0; k < len; k++) { snprintf(tmp, sizeof(tmp), @@ -412,7 +412,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE case TYPE_BIT_STRING: if (value) { len2 = -1; - len = _asn1_get_length_der(value, &len2); + len = _asn1_get_length_der(value, p->value_len, &len2); for (k = 1; k < len; k++) { snprintf(tmp, sizeof(tmp), @@ -424,7 +424,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE case TYPE_OCTET_STRING: if (value) { len2 = -1; - len = _asn1_get_length_der(value, &len2); + len = _asn1_get_length_der(value, p->value_len, &len2); for (k = 0; k < len; k++) { snprintf(tmp, sizeof(tmp), "%02X", (value)[k + len2]); @@ -440,7 +440,7 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE if (!p->down) { if (value) { len3 = -1; - len2 = _asn1_get_length_der(value, &len3); + len2 = _asn1_get_length_der(value, p->value_len, &len3); for (k = 0; k < len2; k++) { snprintf(tmp, sizeof(tmp), "%02X", (value)[k + len3]); @@ -456,10 +456,10 @@ _gnutls_asn1_get_structure_xml(ASN1_TYPE up->left && up->left->value && up->type & CONST_DEFINED_BY && type_field(up->left->type) == TYPE_OBJECT_ID) { + len2 = _asn1_get_length_der(up->value, + up->value_len, &len3); - len2 = _asn1_get_length_der(up->value, &len3); - - if (len2 > 0 && strcmp(p->name, "type") == 0) { + if (len2 > 0 && strcmp(p->name, "type") == 0) { size_t tmp_len = sizeof(tmp); ret = _gnutls_x509_oid_data2string(up->left-> From jas at extundo.com Sat Feb 11 11:19:56 2006 From: jas at extundo.com (Simon Josefsson) Date: Sat, 11 Feb 2006 11:19:56 +0100 Subject: [Help-gnutls] Re: Libtasn1 0.2.18 - Tiny ASN.1 Library - Security release In-Reply-To: (Simon Josefsson's message of "Thu, 09 Feb 2006 16:38:35 +0100") References: Message-ID: On popular demand, we have prepared a minimal set of patches against 0.2.17 that will fix the security problem. There is a branch in CVS called "libtasn1_0_2_17_security" that also contain the minimal fixes for 0.2.17 you'll have to apply to get a security libtasn1. I'm including the patch below. Please review it. Astute readers may recognize that some _asn1* APIs have changed their signature. Those APIs are not exported, and are not intended to be used by external applications. Unfortunately, GnuTLS did use them. We are considering to bump the so version in libtasn1_0_2_17_security and in a new libtasn1 0.3.0. We would then also have to deprecate 0.2.18 because it didn't bump the so version. Comments on this approach are appreciated. Regards, Simon Index: lib/coding.c =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/coding.c,v retrieving revision 1.16 retrieving revision 1.16.2.1 diff -u -p -r1.16 -r1.16.2.1 --- lib/coding.c 16 Jul 2005 11:25:32 -0000 1.16 +++ lib/coding.c 11 Feb 2006 10:00:11 -0000 1.16.2.1 @@ -1,22 +1,23 @@ /* + * Copyright (C) 2004, 2006 Free Software Foundation * Copyright (C) 2002 Fabio Fiorina - * Copyright (C) 2004 Simon Josefsson * - * This file is part of LIBASN1. + * This file is part of LIBTASN1. * - * The LIBTASN1 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 + * The LIBTASN1 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ @@ -148,7 +149,7 @@ _asn1_octet_der(const unsigned char *str { int len_len; - if(der==NULL) return; + if(der==NULL || str_len <= 0) return; _asn1_length_der(str_len,der,&len_len); memcpy(der+len_len,str,str_len); *der_len=str_len+len_len; @@ -196,7 +197,8 @@ _asn1_get_utctime_der(unsigned char *der char temp[20]; if(str==NULL) return; - str_len=_asn1_get_length_der(der,&len_len); + str_len=_asn1_get_length_der(der,*der_len,&len_len); + if (str_len<0) return; memcpy(temp,der+len_len,str_len); *der_len=str_len+len_len; switch(str_len){ @@ -534,7 +536,7 @@ _asn1_insert_tag_der(node_asn *node,unsi /* Return: */ /******************************************************/ void -_asn1_ordering_set(unsigned char *der,node_asn *node) +_asn1_ordering_set(unsigned char *der, int der_len, node_asn *node) { struct vet{ int end; @@ -569,12 +571,14 @@ _asn1_ordering_set(unsigned char *der,no last=p_vet; /* tag value calculation */ - tag=_asn1_get_tag_der(der+counter,&class,&len2); + if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) + return; p_vet->value=(class<<24)|tag; counter+=len2; /* extraction and length */ - len2=_asn1_get_length_der(der+counter,&len); + len2=_asn1_get_length_der(der+counter,der_len-counter,&len); + if (len2<0) return; counter+=len+len2; p_vet->end=counter; @@ -626,7 +630,7 @@ _asn1_ordering_set(unsigned char *der,no /* Return: */ /******************************************************/ void -_asn1_ordering_set_of(unsigned char *der,node_asn *node) +_asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node) { struct vet{ int end; @@ -661,10 +665,16 @@ _asn1_ordering_set_of(unsigned char *der last=p_vet; /* extraction of tag and length */ - _asn1_get_tag_der(der+counter,&class,&len); - counter+=len; - len2=_asn1_get_length_der(der+counter,&len); - counter+=len+len2; + if (der_len-counter > 0) { + + if (_asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS) + return; + counter+=len; + + len2=_asn1_get_length_der(der+counter,der_len-counter,&len); + if (len2<0) return; + counter+=len+len2; + } p_vet->end=counter; p=p->right; @@ -804,7 +814,8 @@ asn1_der_coding(ASN1_TYPE element,const _asn1_error_description_value_not_found(p,ErrorDescription); return ASN1_VALUE_NOT_FOUND; } - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len, &len3); + if (len2<0) return ASN1_DER_ERROR; max_len -= len2+len3; if(max_len>=0) memcpy(der+counter,p->value,len3+len2); @@ -846,7 +857,8 @@ asn1_der_coding(ASN1_TYPE element,const _asn1_error_description_value_not_found(p,ErrorDescription); return ASN1_VALUE_NOT_FOUND; } - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len,&len3); + if (len2<0) return ASN1_DER_ERROR; max_len-=len2+len3; if(max_len>=0) memcpy(der+counter,p->value,len3+len2); @@ -858,7 +870,8 @@ asn1_der_coding(ASN1_TYPE element,const _asn1_error_description_value_not_found(p,ErrorDescription); return ASN1_VALUE_NOT_FOUND; } - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len,&len3); + if (len2<0) return ASN1_DER_ERROR; max_len-=len2+len3; if(max_len>=0) memcpy(der+counter,p->value,len3+len2); @@ -870,7 +883,8 @@ asn1_der_coding(ASN1_TYPE element,const _asn1_error_description_value_not_found(p,ErrorDescription); return ASN1_VALUE_NOT_FOUND; } - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len,&len3); + if (len2<0) return ASN1_DER_ERROR; max_len-=len2+len3; if(max_len>=0) memcpy(der+counter,p->value,len3+len2); @@ -903,7 +917,7 @@ asn1_der_coding(ASN1_TYPE element,const len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); if((type_field(p->type)==TYPE_SET) && (max_len>=0)) - _asn1_ordering_set(der+len2,p); + _asn1_ordering_set(der+len2, max_len-len2,p); _asn1_length_der(counter-len2,temp,&len3); max_len-=len3; if(max_len>=0){ @@ -934,8 +948,9 @@ asn1_der_coding(ASN1_TYPE element,const if(move==UP){ len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); - if((type_field(p->type)==TYPE_SET_OF) && (max_len>=0)) - _asn1_ordering_set_of(der+len2,p); + if((type_field(p->type)==TYPE_SET_OF) && (max_len-len2>0)) { + _asn1_ordering_set_of(der+len2, max_len-len2,p); + } _asn1_length_der(counter-len2,temp,&len3); max_len-=len3; if(max_len>=0){ @@ -951,7 +966,8 @@ asn1_der_coding(ASN1_TYPE element,const _asn1_error_description_value_not_found(p,ErrorDescription); return ASN1_VALUE_NOT_FOUND; } - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len,&len3); + if (len2<0) return ASN1_DER_ERROR; max_len-=len2; if(max_len>=0) memcpy(der+counter,p->value+len3,len2); Index: lib/decoding.c =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/decoding.c,v retrieving revision 1.26 retrieving revision 1.26.2.1 diff -u -p -r1.26 -r1.26.2.1 --- lib/decoding.c 16 Jul 2005 11:25:32 -0000 1.26 +++ lib/decoding.c 11 Feb 2006 10:00:11 -0000 1.26.2.1 @@ -1,22 +1,23 @@ /* + * Copyright (C) 2004, 2006 Free Software Foundation * Copyright (C) 2002 Fabio Fiorina - * Copyright (C) 2004 Simon Josefsson * - * This file is part of LIBASN1. + * This file is part of LIBTASN1. * - * The LIBTASN1 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 + * The LIBTASN1 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ @@ -47,11 +48,14 @@ _asn1_error_description_tag_error(node_a signed long -_asn1_get_length_der(const unsigned char *der,int *len) +_asn1_get_length_der(const unsigned char *der, int der_len, int *len) { unsigned long ans; int k,punt; + *len = 0; + if (der_len <= 0) return 0; + if(!(der[0]&128)){ /* short form */ *len=1; @@ -63,7 +67,13 @@ _asn1_get_length_der(const unsigned char punt=1; if(k){ /* definite length method */ ans=0; - while(punt<=k) ans=ans*256+der[punt++]; + while(punt<=k && punt < der_len) { + unsigned long last = ans; + ans=ans*256+der[punt++]; + if (ans < last) + /* we wrapped around, no bignum support... */ + return -2; + } } else{ /* indefinite length method */ ans=-1; @@ -77,12 +87,14 @@ _asn1_get_length_der(const unsigned char -unsigned int -_asn1_get_tag_der(const unsigned char *der,unsigned char *class,int *len) +int +_asn1_get_tag_der(const unsigned char *der, int der_len, + unsigned char *class,int *len, unsigned long *tag) { int punt,ris; - if (der==NULL || len == NULL) return ASN1_DER_ERROR; + if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR; + *class=der[0]&0xE0; if((der[0]&0x1F)!=0x1F){ /* short form */ @@ -93,25 +105,46 @@ _asn1_get_tag_der(const unsigned char *d /* Long form */ punt=1; ris=0; - while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F); - ris=ris*128+(der[punt++]&0x7F); + while(punt <= der_len && der[punt]&128) + { + int last = ris; + ris=ris*128+(der[punt++]&0x7F); + if (ris < last) + /* wrapper around, and no bignums... */ + return ASN1_DER_ERROR; + } + if (punt >= der_len) + return ASN1_DER_ERROR; + { + int last = ris; + ris=ris*128+(der[punt++]&0x7F); + if (ris < last) + /* wrapper around, and no bignums... */ + return ASN1_DER_ERROR; + } *len=punt; } - return ris; + if (tag) *tag = ris; + return ASN1_SUCCESS; } int -_asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len) +_asn1_get_octet_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size, int *str_len) { int len_len; + if (der_len <= 0) return ASN1_GENERIC_ERROR; + /* if(str==NULL) return ASN1_SUCCESS; */ - *str_len=_asn1_get_length_der(der,&len_len); + *str_len=_asn1_get_length_der(der, der_len, &len_len); + + if (*str_len < 0) + return ASN1_DER_ERROR; - *der_len=*str_len+len_len; + *ret_len=*str_len+len_len; if ( str_size >= *str_len) memcpy(str,der+len_len,*str_len); else { @@ -126,17 +159,17 @@ _asn1_get_octet_der(const unsigned char /* Returns ASN1_SUCCESS on success or an error code on error. */ int -_asn1_get_time_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size) +_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size) { int len_len,str_len; - if(str==NULL) return ASN1_DER_ERROR; - str_len=_asn1_get_length_der(der,&len_len); + if(der_len <=0 || str==NULL) return ASN1_DER_ERROR; + str_len=_asn1_get_length_der(der, der_len, &len_len); if (str_len < 0 || str_size < str_len) return ASN1_DER_ERROR; memcpy(str,der+len_len,str_len); str[str_len]=0; - *der_len=str_len+len_len; + *ret_len=str_len+len_len; return ASN1_SUCCESS; } @@ -144,14 +177,19 @@ _asn1_get_time_der(const unsigned char * void -_asn1_get_objectid_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size) +_asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size) { int len_len,len,k; char temp[20]; unsigned long val,val1; - if(str==NULL) return; - len=_asn1_get_length_der(der,&len_len); + *ret_len = 0; + if (str && str_size > 0) str[0] = 0; /* no oid */ + + if(str==NULL || der_len <= 0) return; + len=_asn1_get_length_der(der,der_len, &len_len); + + if (len < 0 || len > der_len || len_len > der_len) return; val1=der[len_len]/40; val=der[len_len]-val1*40; @@ -170,20 +208,24 @@ _asn1_get_objectid_der(const unsigned ch val=0; } } - *der_len=len+len_len; + *ret_len=len+len_len; } int -_asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len) +_asn1_get_bit_der(const unsigned char *der, int der_len, + int *ret_len,unsigned char *str, int str_size, int *bit_len) { int len_len,len_byte; - len_byte=_asn1_get_length_der(der,&len_len)-1; + if (der_len <=0) return ASN1_GENERIC_ERROR; + len_byte=_asn1_get_length_der(der,der_len,&len_len)-1; + if (len_byte < 0) + return ASN1_DER_ERROR; - *der_len=len_byte+len_len+1; + *ret_len=len_byte+len_len+1; *bit_len=len_byte*8-der[len_len]; if (str_size >= len_byte) @@ -199,14 +241,15 @@ _asn1_get_bit_der(const unsigned char *d int -_asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len) +_asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len) { node_asn *p; int counter,len2,len3,is_tag_implicit; unsigned long tag,tag_implicit=0; unsigned char class,class2,class_implicit=0; - + if (der_len <= 0) return ASN1_GENERIC_ERROR; + counter=is_tag_implicit=0; if(node->type&CONST_TAG){ @@ -219,9 +262,14 @@ _asn1_extract_tag_der(node_asn *node,con else class2=CONTEXT_SPECIFIC; if(p->type&CONST_EXPLICIT){ - tag=_asn1_get_tag_der(der+counter,&class,&len2); + if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; counter+=len2; - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,der_len-counter, &len2); + if (len3 < 0) + return ASN1_DER_ERROR; counter+=len2; if(!is_tag_implicit){ if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10))) @@ -251,7 +299,11 @@ _asn1_extract_tag_der(node_asn *node,con } if(is_tag_implicit){ - tag=_asn1_get_tag_der(der+counter,&class,&len2); + if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; + if((class!=class_implicit) || (tag!=tag_implicit)){ if(type_field(node->type)==TYPE_OCTET_STRING){ class_implicit |= STRUCTURED; @@ -265,11 +317,15 @@ _asn1_extract_tag_der(node_asn *node,con else{ if(type_field(node->type)==TYPE_TAG){ counter=0; - *der_len=counter; + *ret_len=counter; return ASN1_SUCCESS; } - tag=_asn1_get_tag_der(der+counter,&class,&len2); + if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; + switch(type_field(node->type)){ case TYPE_NULL: if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR; @@ -323,7 +379,7 @@ _asn1_extract_tag_der(node_asn *node,con } counter+=len2; - *der_len=counter; + *ret_len=counter; return ASN1_SUCCESS; } @@ -375,7 +431,7 @@ _asn1_delete_not_used(node_asn *node) asn1_retCode -_asn1_get_octet_string(const unsigned char* der,node_asn *node,int* len) +_asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len) { int len2,len3,counter,counter2,counter_end,tot_len,indefinite; char *temp,*temp2; @@ -384,7 +440,9 @@ _asn1_get_octet_string(const unsigned ch if(*(der-1) & STRUCTURED){ tot_len=0; - indefinite=_asn1_get_length_der(der,&len3); + indefinite=_asn1_get_length_der(der, *len, &len3); + if (indefinite < -1) + return ASN1_DER_ERROR; counter+=len3; if(indefinite>=0) indefinite+=len3; @@ -404,7 +462,7 @@ _asn1_get_octet_string(const unsigned ch counter++; - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,*len-counter, &len3); if(len2 <= 0) return ASN1_DER_ERROR; counter+=len3+len2; @@ -422,24 +480,33 @@ _asn1_get_octet_string(const unsigned ch _asn1_length_der(tot_len,temp,&len2); tot_len+=len2; temp2=temp+len2; - len2=_asn1_get_length_der(der,&len3); + len2=_asn1_get_length_der(der,*len,&len3); + if(len2 < -1) return ASN1_DER_ERROR; counter2=len3+1; if(indefinite==-1) counter_end=counter-2; else counter_end=counter; while(counter2 *len) return ASN1_DER_ERROR; if(node) _asn1_set_value(node,der,len3+len2); counter=len3+len2; @@ -452,10 +519,10 @@ _asn1_get_octet_string(const unsigned ch asn1_retCode -_asn1_get_indefinite_length_string(const unsigned char* der,int* len) +_asn1_get_indefinite_length_string(const unsigned char* der, int* len) { int len2,len3,counter,indefinite; - unsigned int tag; + unsigned long tag; unsigned char class; counter=indefinite=0; @@ -470,9 +537,13 @@ _asn1_get_indefinite_length_string(const else continue; } - tag=_asn1_get_tag_der(der+counter,&class,&len2); + if(_asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > *len) + return ASN1_DER_ERROR; counter+=len2; - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter, *len-counter,&len3); + if(len2 < -1) return ASN1_DER_ERROR; if(len2 == -1){ indefinite++; counter+=1; @@ -520,7 +591,7 @@ asn1_der_decoding(ASN1_TYPE *element,con char temp[128]; int counter,len2,len3,len4,move,ris,tlen; unsigned char class,*temp2; - unsigned int tag; + unsigned long tag; int indefinite, result; const unsigned char* der = ider; @@ -563,11 +634,11 @@ asn1_der_decoding(ASN1_TYPE *element,con while(p2){ if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,&len2); + ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2); else{ p3=p2->down; while(p3){ - ris=_asn1_extract_tag_der(p3,der+counter,&len2); + ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2); if(ris==ASN1_SUCCESS) break; p3=p3->right; } @@ -606,7 +677,7 @@ asn1_der_decoding(ASN1_TYPE *element,con if(type_field(p->type)==TYPE_CHOICE){ while(p->down){ if(counterdown,der+counter,&len2); + ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2); else ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ @@ -642,7 +713,7 @@ asn1_der_decoding(ASN1_TYPE *element,con if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR; } - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2); + if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); if(ris!=ASN1_SUCCESS){ if(p->type&CONST_OPTION){ p->type|=CONST_NOT_USED; @@ -683,13 +754,15 @@ asn1_der_decoding(ASN1_TYPE *element,con move=RIGHT; break; case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter, &len3); + if(len2 < 0) return ASN1_DER_ERROR; + if (len2+len3 > len-counter) return ASN1_DER_ERROR; _asn1_set_value(p,der+counter,len3+len2); counter+=len3+len2; move=RIGHT; break; case TYPE_OBJECT_ID: - _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp)); + _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp)); tlen = strlen(temp); if( tlen > 0) _asn1_set_value(p,temp,tlen+1); @@ -697,7 +770,7 @@ asn1_der_decoding(ASN1_TYPE *element,con move=RIGHT; break; case TYPE_TIME: - result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1); + result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1); if (result != ASN1_SUCCESS) { asn1_delete_structure(element); return result; @@ -716,14 +789,18 @@ asn1_der_decoding(ASN1_TYPE *element,con move=RIGHT; break; case TYPE_GENERALSTRING: - len2=_asn1_get_length_der(der+counter,&len3); - _asn1_set_value(p,der+counter,len3+len2); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; + if (len3+len2 > len-counter) return ASN1_DER_ERROR; + _asn1_set_value(p,der+counter,len3+len2); counter+=len3+len2; move=RIGHT; break; case TYPE_BIT_STRING: - len2=_asn1_get_length_der(der+counter,&len3); - _asn1_set_value(p,der+counter,len3+len2); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; + if (len3+len2 > len-counter) return ASN1_DER_ERROR; + _asn1_set_value(p,der+counter,len3+len2); counter+=len3+len2; move=RIGHT; break; @@ -732,10 +809,12 @@ asn1_der_decoding(ASN1_TYPE *element,con len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); if(len2==-1){ /* indefinite length method */ - if((der[counter]) || der[counter+1]){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } + if (len-counter+1 > 0) { + if((der[counter]) || der[counter+1]){ + asn1_delete_structure(element); + return ASN1_DER_ERROR; + } + } else return ASN1_DER_ERROR; counter+=2; } else{ /* definite length method */ @@ -747,7 +826,8 @@ asn1_der_decoding(ASN1_TYPE *element,con move=RIGHT; } else{ /* move==DOWN || move==RIGHT */ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < -1) return ASN1_DER_ERROR; counter+=len2; if(len3>0){ _asn1_ltostr(counter+len3,temp); @@ -806,7 +886,8 @@ asn1_der_decoding(ASN1_TYPE *element,con } } else{ /* move==DOWN || move==RIGHT */ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < -1) return ASN1_DER_ERROR; counter+=len2; if(len3){ if(len3>0){ /* definite length method */ @@ -828,9 +909,13 @@ asn1_der_decoding(ASN1_TYPE *element,con move=RIGHT; break; case TYPE_ANY: - tag=_asn1_get_tag_der(der+counter,&class,&len2); - len4=_asn1_get_length_der(der+counter+len2,&len3); - + if(_asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > len) + return ASN1_DER_ERROR; + len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); + if(len4 < -1) return ASN1_DER_ERROR; + if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR; if(len4 != -1){ len2+=len4; _asn1_length_der(len2+len3,NULL,&len4); @@ -955,7 +1040,7 @@ asn1_der_decoding_element(ASN1_TYPE *str int nameLen=MAX_NAME_SIZE*10-1,state; int counter,len2,len3,len4,move,ris, tlen; unsigned char class,*temp2; - unsigned int tag; + unsigned long tag; int indefinite, result; const unsigned char* der = ider; @@ -1024,11 +1109,11 @@ asn1_der_decoding_element(ASN1_TYPE *str while(p2){ if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,&len2); + ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2); else{ p3=p2->down; while(p3){ - ris=_asn1_extract_tag_der(p3,der+counter,&len2); + ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2); if(ris==ASN1_SUCCESS) break; p3=p3->right; } @@ -1067,7 +1152,7 @@ asn1_der_decoding_element(ASN1_TYPE *str if(type_field(p->type)==TYPE_CHOICE){ while(p->down){ if(counterdown,der+counter,&len2); + ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2); else ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ @@ -1103,7 +1188,7 @@ asn1_der_decoding_element(ASN1_TYPE *str if(counter>len2) ris=ASN1_TAG_ERROR; } - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2); + if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); if(ris!=ASN1_SUCCESS){ if(p->type&CONST_OPTION){ p->type|=CONST_NOT_USED; @@ -1156,8 +1241,10 @@ asn1_der_decoding_element(ASN1_TYPE *str move=RIGHT; break; case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; if(state==FOUND){ + if (len3+len2 > len-counter) return ASN1_DER_ERROR; _asn1_set_value(p,der+counter,len3+len2); if(p==nodeFound) state=EXIT; @@ -1167,7 +1254,7 @@ asn1_der_decoding_element(ASN1_TYPE *str break; case TYPE_OBJECT_ID: if(state==FOUND){ - _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp)); + _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp)); tlen = strlen(temp); if (tlen > 0) @@ -1176,7 +1263,8 @@ asn1_der_decoding_element(ASN1_TYPE *str if(p==nodeFound) state=EXIT; } else{ - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; len2+=len3; } @@ -1185,7 +1273,7 @@ asn1_der_decoding_element(ASN1_TYPE *str break; case TYPE_TIME: if(state==FOUND){ - result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1); + result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1); if (result != ASN1_SUCCESS) { asn1_delete_structure(structure); return result; @@ -1198,7 +1286,8 @@ asn1_der_decoding_element(ASN1_TYPE *str if(p==nodeFound) state=EXIT; } else{ - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; len2+=len3; } @@ -1219,8 +1308,10 @@ asn1_der_decoding_element(ASN1_TYPE *str move=RIGHT; break; case TYPE_GENERALSTRING: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; if(state==FOUND){ + if (len3+len2 > len-counter) return ASN1_DER_ERROR; _asn1_set_value(p,der+counter,len3+len2); if(p==nodeFound) state=EXIT; @@ -1229,8 +1320,10 @@ asn1_der_decoding_element(ASN1_TYPE *str move=RIGHT; break; case TYPE_BIT_STRING: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; if(state==FOUND){ + if (len3+len2 > len-counter) return ASN1_DER_ERROR; _asn1_set_value(p,der+counter,len3+len2); if(p==nodeFound) state=EXIT; @@ -1260,12 +1353,14 @@ asn1_der_decoding_element(ASN1_TYPE *str } else{ /* move==DOWN || move==RIGHT */ if(state==OTHER_BRANCH){ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < 0) return ASN1_DER_ERROR; counter+=len2+len3; move=RIGHT; } else { /* state==SAME_BRANCH or state==FOUND */ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < 0) return ASN1_DER_ERROR; counter+=len2; if(len3>0){ _asn1_ltostr(counter+len3,temp); @@ -1315,12 +1410,14 @@ asn1_der_decoding_element(ASN1_TYPE *str } else{ /* move==DOWN || move==RIGHT */ if(state==OTHER_BRANCH){ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < 0) return ASN1_DER_ERROR; counter+=len2+len3; move=RIGHT; } else{ /* state==FOUND or state==SAME_BRANCH */ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < 0) return ASN1_DER_ERROR; counter+=len2; if(len3){ _asn1_ltostr(counter+len3,temp); @@ -1339,9 +1436,14 @@ asn1_der_decoding_element(ASN1_TYPE *str break; case TYPE_ANY: - tag=_asn1_get_tag_der(der+counter,&class,&len2); - len4=_asn1_get_length_der(der+counter+len2,&len3); - + if(_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > len) + return ASN1_DER_ERROR; + + len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); + if(len4 < -1) return ASN1_DER_ERROR; + if(len4 != -1){ len2+=len4; if(state==FOUND){ @@ -1549,7 +1651,7 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele node_asn *node,*node_to_find,*p,*p2,*p3; int counter,len2,len3,len4,move,ris; unsigned char class; - unsigned int tag; + unsigned long tag; int indefinite; const unsigned char* der = ider; @@ -1597,10 +1699,10 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele while(p2){ if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */ if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,&len2); + ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2); else{ p3=p2->down; - ris=_asn1_extract_tag_der(p3,der+counter,&len2); + ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2); } if(ris==ASN1_SUCCESS){ p2->type&=~CONST_NOT_USED; @@ -1617,11 +1719,11 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele if(type_field(p->type)==TYPE_CHOICE){ p=p->down; - ris=_asn1_extract_tag_der(p,der+counter,&len2); + ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); if(p==node_to_find) *start=counter; } - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2); + if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); if(ris!=ASN1_SUCCESS){ if(p->type&CONST_OPTION){ p->type|=CONST_NOT_USED; @@ -1650,17 +1752,20 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele move=RIGHT; break; case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; counter+=len3+len2; move=RIGHT; break; case TYPE_OBJECT_ID: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; counter+=len2+len3; move=RIGHT; break; case TYPE_TIME: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; counter+=len2+len3; move=RIGHT; break; @@ -1672,18 +1777,21 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele move=RIGHT; break; case TYPE_GENERALSTRING: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; counter+=len3+len2; move=RIGHT; break; case TYPE_BIT_STRING: - len2=_asn1_get_length_der(der+counter,&len3); + len2=_asn1_get_length_der(der+counter,len-counter,&len3); + if(len2 < 0) return ASN1_DER_ERROR; counter+=len3+len2; move=RIGHT; break; case TYPE_SEQUENCE: case TYPE_SET: if(move!=UP){ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < -1) return ASN1_DER_ERROR; counter+=len2; if(len3==0) move=RIGHT; else move=DOWN; @@ -1696,7 +1804,8 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele break; case TYPE_SEQUENCE_OF: case TYPE_SET_OF: if(move!=UP){ - len3=_asn1_get_length_der(der+counter,&len2); + len3=_asn1_get_length_der(der+counter,len-counter,&len2); + if(len3 < -1) return ASN1_DER_ERROR; counter+=len2; if((len3==-1) && !der[counter] && !der[counter+1]) counter+=2; @@ -1714,9 +1823,14 @@ asn1_der_decoding_startEnd(ASN1_TYPE ele move=RIGHT; break; case TYPE_ANY: - tag=_asn1_get_tag_der(der+counter,&class,&len2); - len4=_asn1_get_length_der(der+counter+len2,&len3); - + if (_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter+len2 > len) + return ASN1_DER_ERROR; + + len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); + if(len4 < -1) return ASN1_DER_ERROR; + if(len4 != -1){ counter+=len2+len4+len3; } @@ -1887,8 +2001,9 @@ asn1_expand_any_defined_by(ASN1_TYPE def result=asn1_create_element(definitions,name,&aux); if(result == ASN1_SUCCESS){ _asn1_set_name(aux,p->name); - len2=_asn1_get_length_der(p->value,&len3); - + len2=_asn1_get_length_der(p->value,p->value_len,&len3); + if(len2 < 0) return ASN1_DER_ERROR; + result=asn1_der_decoding(&aux,p->value+len3,len2, errorDescription); if(result == ASN1_SUCCESS){ @@ -2051,8 +2166,9 @@ asn1_expand_octet_string(ASN1_TYPE defin result=asn1_create_element(definitions,name,&aux); if(result == ASN1_SUCCESS){ _asn1_set_name(aux,octetNode->name); - len2=_asn1_get_length_der(octetNode->value,&len3); - + len2=_asn1_get_length_der(octetNode->value,octetNode->value_len,&len3); + if(len2 < 0) return ASN1_DER_ERROR; + result=asn1_der_decoding(&aux,octetNode->value+len3,len2, errorDescription); if(result == ASN1_SUCCESS){ Index: lib/der.h =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/der.h,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -u -p -r1.6 -r1.6.2.1 --- lib/der.h 30 Jul 2003 19:52:56 -0000 1.6 +++ lib/der.h 11 Feb 2006 10:00:11 -0000 1.6.2.1 @@ -28,23 +28,23 @@ #define TAG_NULL 0x05 #define TAG_GENERALSTRING 0x1B -unsigned int _asn1_get_tag_der(const unsigned char *der, - unsigned char *class,int *len); +int _asn1_get_tag_der(const unsigned char *der, int der_len, + unsigned char *class,int *len, unsigned long *tag); void _asn1_octet_der(const unsigned char *str,int str_len, unsigned char *der,int *der_len); -asn1_retCode _asn1_get_octet_der(const unsigned char *der, - int *der_len,unsigned char *str,int str_size, int *str_len); +asn1_retCode _asn1_get_octet_der(const unsigned char *der, int der_len, + int *ret_len,unsigned char *str,int str_size, int *str_len); void _asn1_bit_der(const unsigned char *str,int bit_len, unsigned char *der,int *der_len); -asn1_retCode _asn1_get_bit_der(const unsigned char *der, - int *der_len,unsigned char *str, int str_size, +asn1_retCode _asn1_get_bit_der(const unsigned char *der, int der_len, + int *ret_len,unsigned char *str, int str_size, int *bit_len); -signed long _asn1_get_length_der(const unsigned char *der,int *len); +signed long _asn1_get_length_der(const unsigned char *der,int der_len, int *len); void _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len); Index: lib/element.c =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/element.c,v retrieving revision 1.22 retrieving revision 1.22.2.1 diff -u -p -r1.22 -r1.22.2.1 --- lib/element.c 16 Jul 2005 11:25:32 -0000 1.22 +++ lib/element.c 11 Feb 2006 10:00:11 -0000 1.22.2.1 @@ -1,22 +1,23 @@ /* + * Copyright (C) 2004, 2006 Free Software Foundation * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina - * Copyright (C) 2004 Simon Josefsson * - * This file is part of LIBASN1. + * This file is part of LIBTASN1. * - * The LIBTASN1 library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public + * The LIBTASN1 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ /*****************************************************/ @@ -677,7 +678,7 @@ asn1_read_value(ASN1_TYPE root,const cha } else{ len2=-1; - if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; + if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; } break; case TYPE_OBJECT_ID: @@ -709,22 +710,23 @@ asn1_read_value(ASN1_TYPE root,const cha break; case TYPE_OCTET_STRING: len2=-1; - if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; + if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; break; case TYPE_GENERALSTRING: len2=-1; - if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; + if (_asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; break; case TYPE_BIT_STRING: len2=-1; - if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; + if (_asn1_get_bit_der(node->value,node->value_len,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; break; case TYPE_CHOICE: PUT_STR_VALUE( value, value_size, node->down->name); break; case TYPE_ANY: len3=-1; - len2=_asn1_get_length_der(node->value,&len3); + len2=_asn1_get_length_der(node->value,node->value_len,&len3); + if (len2 < 0) return ASN1_DER_ERROR; PUT_VALUE( value, value_size, node->value+len3, len2); break; default: Index: lib/libtasn1.h =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/libtasn1.h,v retrieving revision 1.30 retrieving revision 1.30.2.1 diff -u -p -r1.30 -r1.30.2.1 --- lib/libtasn1.h 31 Aug 2005 13:17:47 -0000 1.30 +++ lib/libtasn1.h 11 Feb 2006 10:00:11 -0000 1.30.2.1 @@ -1,6 +1,6 @@ /* + * Copyright (C) 2004, 2005, 2006 Free Software Foundation * Copyright (C) 2002 Fabio Fiorina - * Copyright (C) 2004, 2005 Simon Josefsson * * This file is part of LIBTASN1. * @@ -108,6 +108,7 @@ typedef struct node_asn_struct{ char *name; /* Node name */ unsigned int type; /* Node type */ unsigned char *value; /* Node value */ + int value_len; struct node_asn_struct *down; /* Pointer to the son node */ struct node_asn_struct *right; /* Pointer to the brother node */ struct node_asn_struct *left; /* Pointer to the next list element */ Index: lib/parser_aux.c =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/parser_aux.c,v retrieving revision 1.13 retrieving revision 1.13.2.1 diff -u -p -r1.13 -r1.13.2.1 --- lib/parser_aux.c 16 Jul 2005 11:25:32 -0000 1.13 +++ lib/parser_aux.c 11 Feb 2006 10:00:11 -0000 1.13.2.1 @@ -1,22 +1,23 @@ /* + * Copyright (C) 2004, 2006 Free Software Foundation * Copyright (C) 2000,2001 Fabio Fiorina - * Copyright (C) 2004 Simon Josefsson * - * This file is part of LIBASN1. + * This file is part of LIBTASN1. * - * The LIBTASN1 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 + * The LIBTASN1 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ #include @@ -187,10 +188,12 @@ _asn1_set_value(node_asn *node,const uns if(node->value){ _asn1_free(node->value); node->value=NULL; + node->value_len = 0; } if(!len) return node; node->value=(unsigned char *) _asn1_malloc(len); if (node->value==NULL) return NULL; + node->value_len = len; memcpy(node->value,value,len); return node; Index: lib/structure.c =================================================================== RCS file: /cvs/gnutls/libtasn1/lib/structure.c,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -u -p -r1.21 -r1.21.2.1 --- lib/structure.c 16 Jul 2005 11:25:32 -0000 1.21 +++ lib/structure.c 11 Feb 2006 10:00:11 -0000 1.21.2.1 @@ -1,22 +1,23 @@ /* + * Copyright (C) 2004, 2006 Free Software Foundation * Copyright (C) 2002 Fabio Fiorina - * Copyright (C) 2004 Simon Josefsson * - * This file is part of LIBASN1. + * This file is part of LIBTASN1. * - * The LIBTASN1 library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public + * The LIBTASN1 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 + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ @@ -362,7 +363,8 @@ _asn1_copy_structure3(node_asn *source_n case TYPE_OCTET_STRING: case TYPE_BIT_STRING: case TYPE_GENERALSTRING: case TYPE_INTEGER: len2=-1; - len=_asn1_get_length_der(p_s->value,&len2); + len=_asn1_get_length_der(p_s->value,p_s->value_len,&len2); + if (len < 0) return NULL; _asn1_set_value(p_d,p_s->value,len+len2); break; default: @@ -726,17 +728,19 @@ asn1_print_structure(FILE *out,ASN1_TYPE case TYPE_INTEGER: if(p->value){ len2=-1; - len=_asn1_get_length_der(p->value,&len2); + len=_asn1_get_length_der(p->value,p->value_len,&len2); fprintf(out," value:0x"); - for(k=0;kvalue)[k+len2]); + if (len > 0) + for(k=0;kvalue)[k+len2]); } break; case TYPE_ENUMERATED: if(p->value){ len2=-1; - len=_asn1_get_length_der(p->value,&len2); + len=_asn1_get_length_der(p->value,p->value_len,&len2); fprintf(out," value:0x"); - for(k=0;kvalue)[k+len2]); + if (len > 0) + for(k=0;kvalue)[k+len2]); } break; case TYPE_TIME: @@ -751,25 +755,30 @@ asn1_print_structure(FILE *out,ASN1_TYPE case TYPE_BIT_STRING: if(p->value){ len2=-1; - len=_asn1_get_length_der(p->value,&len2); - fprintf(out," value(%i):",(len-1)*8-(p->value[len2])); - for(k=1;kvalue)[k+len2]); + len=_asn1_get_length_der(p->value,p->value_len,&len2); + if (len>0) + { + fprintf(out," value(%i):",(len-1)*8-(p->value[len2])); + for(k=1;kvalue)[k+len2]); + } } break; case TYPE_OCTET_STRING: if(p->value){ len2=-1; - len=_asn1_get_length_der(p->value,&len2); + len=_asn1_get_length_der(p->value,p->value_len,&len2); fprintf(out," value:"); - for(k=0;kvalue)[k+len2]); + if (len>0) + for(k=0;kvalue)[k+len2]); } break; case TYPE_GENERALSTRING: if(p->value){ len2=-1; - len=_asn1_get_length_der(p->value,&len2); + len=_asn1_get_length_der(p->value,p->value_len,&len2); fprintf(out," value:"); - for(k=0;kvalue)[k+len2]); + if (len>0) + for(k=0;kvalue)[k+len2]); } break; case TYPE_OBJECT_ID: @@ -778,9 +787,10 @@ asn1_print_structure(FILE *out,ASN1_TYPE case TYPE_ANY: if(p->value){ len3=-1; - len2=_asn1_get_length_der(p->value,&len3); + len2=_asn1_get_length_der(p->value,p->value_len,&len3); fprintf(out," value:"); - for(k=0;kvalue)[k+len3]); + if (len2>0) + for(k=0;kvalue)[k+len3]); } break; case TYPE_SET: From whatever at fsrz.net Mon Feb 20 21:10:54 2006 From: whatever at fsrz.net (Rich Fought) Date: Mon, 20 Feb 2006 14:10:54 -0600 Subject: [Help-gnutls] Using encrypted keys Message-ID: <003301c63659$c13ae710$5103a8c0@psislidell.com> So far in my project I have been using decrypted server keys and gnutls_certificate_set_x509_key_file to read them (along with the cert) into the credentials structure. Now I wish to transition to encrypted keys. From the documentation here's what I think I need to do, please let me know if there is an easier or different way: - Since gnutls_certificate_set_x509_key_file does not support encrypted keys, I have to read the encrypted key contents into memory and use gnutls_x509_privkey_import_pkcs8 to get they key into the decrypted gnutls_x509_privkey type. (Since I am using OpenSSL to generate my keys, I will have to convert to PKCS8 with PKCS12 encryption first.) - I then need to read the certificate contents into memory and use gnutls_x509_crt_import to get it into the gnutls_x509_crt type. - I then need to use gnutls_certificate_set_x509_key to store the imported cert/key into the credentials structure. Sound right? The reason I ask is that I need to write Haskell bindings for these functions and would rather know I am doing the right ones ahead of time. :) Thanks, Rich From jas at extundo.com Tue Feb 21 13:25:47 2006 From: jas at extundo.com (Simon Josefsson) Date: Tue, 21 Feb 2006 13:25:47 +0100 Subject: [Help-gnutls] Re: Using encrypted keys In-Reply-To: <003301c63659$c13ae710$5103a8c0@psislidell.com> (Rich Fought's message of "Mon, 20 Feb 2006 14:10:54 -0600") References: <003301c63659$c13ae710$5103a8c0@psislidell.com> Message-ID: "Rich Fought" writes: > So far in my project I have been using decrypted server keys and > gnutls_certificate_set_x509_key_file to read them (along with the cert) into > the credentials structure. > > Now I wish to transition to encrypted keys. From the documentation here's > what I think I need to do, please let me know if there is an easier or > different way: > > - Since gnutls_certificate_set_x509_key_file does not support encrypted > keys, I have to read the encrypted key contents into memory and use > gnutls_x509_privkey_import_pkcs8 to get they key into the decrypted > gnutls_x509_privkey type. (Since I am using OpenSSL to generate my keys, I > will have to convert to PKCS8 with PKCS12 encryption first.) > > - I then need to read the certificate contents into memory and use > gnutls_x509_crt_import to get it into the gnutls_x509_crt type. > > - I then need to use gnutls_certificate_set_x509_key to store the imported > cert/key into the credentials structure. > > Sound right? The reason I ask is that I need to write Haskell bindings for > these functions and would rather know I am doing the right ones ahead of > time. :) In 1.3.1 we added gnutls_certificate_set_x509_simple_pkcs12_file that is intended to handle encrypted keys and certificates, see the NEWS entry below. Admittedly, it uses the same password for all steps, but that seem to be the common usage. Maybe that function solves your problem? I recall trying it on some encrypted key+cert blobs that are used by OpenSSL-applications; there is a self-test of this in tests/set_pkcs12_cred.c. The PKCS#12 format is quite flexible, so I recommend that you keep the interface minimal in order to have something usable. A fully flexible PKCS#12 API would be very complicated, for no practical gain. Regards, Simon ** New function to set a X.509 private key and certificate pairs, and/or CRLs, from an PKCS#12 file, suggested by Emile van Bergen . The integrity of the PKCS#12 file is protected through a password based MAC; public-key based signatures for integrity protection are not supported. PKCS#12 bags may be encrypted using password derived symmetric keys, public-key based encryption is not supported. The PKCS#8 keys may be encrypted using passwords. The API use the same password for all operations. We believe that any more flexibility create too much complexity that would hurt overall security, but may add more PKCS#12 related APIs if real-world experience indicate otherwise. From jas at extundo.com Fri Feb 24 21:05:10 2006 From: jas at extundo.com (Simon Josefsson) Date: Fri, 24 Feb 2006 21:05:10 +0100 Subject: [Help-gnutls] Re: Using encrypted keys In-Reply-To: <005d01c6396b$97da2e20$5103a8c0@psislidell.com> (Rich Fought's message of "Fri, 24 Feb 2006 11:56:09 -0600") References: <005d01c6396b$97da2e20$5103a8c0@psislidell.com> Message-ID: "Rich Fought" writes: > That function does sound like it would do the trick, and a lot cleaner. > > When does the 1.3.x branch stop being "experimental?" What does this really > mean? > Should I be wary of moving from 1.2.9 to 1.3.x? 1.3.x will turn into 1.4 during the spring, I guess. I wouldn't worry about moving to 1.3.x, it should be stable. There aren't any major re-designs, only new stuff that may break things in minor ways. I view 1.2.x as for production servers, and 1.3.x for everything else. Regards, Simon From whatever at fsrz.net Fri Feb 24 18:56:09 2006 From: whatever at fsrz.net (Rich Fought) Date: Fri, 24 Feb 2006 11:56:09 -0600 Subject: [Help-gnutls] RE: Using encrypted keys In-Reply-To: Message-ID: <005d01c6396b$97da2e20$5103a8c0@psislidell.com> That function does sound like it would do the trick, and a lot cleaner. When does the 1.3.x branch stop being "experimental?" What does this really mean? Should I be wary of moving from 1.2.9 to 1.3.x? Regards, Rich -----Original Message----- From: Simon Josefsson [mailto:jas at extundo.com] Sent: Tuesday, February 21, 2006 6:26 AM To: Rich Fought Cc: help-gnutls at gnu.org Subject: Re: Using encrypted keys "Rich Fought" writes: > So far in my project I have been using decrypted server keys and > gnutls_certificate_set_x509_key_file to read them (along with the > cert) into the credentials structure. > > Now I wish to transition to encrypted keys. From the documentation > here's what I think I need to do, please let me know if there is an > easier or different way: > > - Since gnutls_certificate_set_x509_key_file does not support > encrypted keys, I have to read the encrypted key contents into memory > and use > gnutls_x509_privkey_import_pkcs8 to get they key into the decrypted > gnutls_x509_privkey type. (Since I am using OpenSSL to generate my > keys, I will have to convert to PKCS8 with PKCS12 encryption first.) > > - I then need to read the certificate contents into memory and use > gnutls_x509_crt_import to get it into the gnutls_x509_crt type. > > - I then need to use gnutls_certificate_set_x509_key to store the > imported cert/key into the credentials structure. > > Sound right? The reason I ask is that I need to write Haskell > bindings for these functions and would rather know I am doing the > right ones ahead of time. :) In 1.3.1 we added gnutls_certificate_set_x509_simple_pkcs12_file that is intended to handle encrypted keys and certificates, see the NEWS entry below. Admittedly, it uses the same password for all steps, but that seem to be the common usage. Maybe that function solves your problem? I recall trying it on some encrypted key+cert blobs that are used by OpenSSL-applications; there is a self-test of this in tests/set_pkcs12_cred.c. The PKCS#12 format is quite flexible, so I recommend that you keep the interface minimal in order to have something usable. A fully flexible PKCS#12 API would be very complicated, for no practical gain. Regards, Simon ** New function to set a X.509 private key and certificate pairs, and/or CRLs, from an PKCS#12 file, suggested by Emile van Bergen . The integrity of the PKCS#12 file is protected through a password based MAC; public-key based signatures for integrity protection are not supported. PKCS#12 bags may be encrypted using password derived symmetric keys, public-key based encryption is not supported. The PKCS#8 keys may be encrypted using passwords. The API use the same password for all operations. We believe that any more flexibility create too much complexity that would hurt overall security, but may add more PKCS#12 related APIs if real-world experience indicate otherwise. From jas at extundo.com Tue Feb 28 13:49:42 2006 From: jas at extundo.com (Simon Josefsson) Date: Tue, 28 Feb 2006 13:49:42 +0100 Subject: [Help-gnutls] Libtasn1 0.3.0 Message-ID: The main focus of this release is a native port to Microsoft Windows. The project files for Visual Studio 2005 are included in the windows/ directory. With them, you can build the library, the self-tests and command line ASN.1 parser tool. This build pass self tests and appear to work, but is still experimental. The Windows port is the first step towards a more fully functional port of GnuTLS to Windows with, e.g., support for Windows CAPI CA certificates. It is not yet clear how, when or if that port will be finished, we invite feedback, support and any monetary donations. This work is done in an co-operation with Simon Josefsson Datakonsult, Lumiad and E-advies. This release export the functions that GnuTLS need internally, so that GnuTLS and other projects can use them without problem. Below is your regular release announcement... Libtasn1 is a standalone library written in C for manipulating ASN.1 objects including DER/BER encoding and DER/BER decoding. Libtasn1 is used by GnuTLS to manipulate X.509 objects and by GNU Shishi to handle Kerberos V5 packets. Version 0.3.0 - Export DER utility functions, mostly so that GnuTLS can avoid using libtasn1 internals. - The _asn1* symbols are not exported in the shared library file (when using GNU ld). - The library can now be built using Visual Studio, and the project files are included in windows/. - New public APIs: asn1_get_tag_der asn1_octet_der asn1_get_octet_der asn1_bit_der asn1_get_bit_der asn1_get_length_der asn1_length_der Commercial support contracts for Libtasn1 are available, and they help finance continued maintenance. Simon Josefsson Datakonsult, a Stockholm based privately held company, is currently funding Libtasn1 maintenance. We are always looking for interesting development projects. If you need help to use Libtasn1, or want to help others, you are invited to join our help-gnutls mailing list, see: . Homepage: http://josefsson.org/libtasn1/ Manual in many formats: http://josefsson.org/gnutls/manual/libtasn1/ Here are the compressed sources: ftp://ftp.gnutls.org/pub/gnutls/libtasn1/libtasn1-0.3.0.tar.gz (1.2MB) http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.3.0.tar.gz Here are GPG detached signatures using key 0xB565716F: ftp://ftp.gnutls.org/pub/gnutls/libtasn1/libtasn1-0.3.0.tar.gz.sig http://josefsson.org/gnutls/releases/libtasn1/libtasn1-0.3.0.tar.gz.sig Here are the SHA-1 checksums: 944117dfa77550ac425121f8aa1489be97a6b522 libtasn1-0.3.0.tar.gz 0f38814e0eebe0ccd6ed165c286d1e2e9ea6c82c libtasn1-0.3.0.tar.gz.sig Enjoy, Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 422 bytes Desc: not available URL: