Ticket #715: polarssl_proper.2.including_cert_chain_fix.patch

File polarssl_proper.2.including_cert_chain_fix.patch, 46.5 KB (added by er13, 6 months ago)
  • CHANGELOG

     
    147147    * libpcap 1.0.0 
    148148    * libpng 1.2.42 
    149149    * libpopt 1.15 
     150    * libpolarssl 0.12.1 
    150151    * liblzo 2.03 
    151152    * libneon 0.29.3 
    152153    * linux-atm 2.5.0 
  • make/libs/Makefile.in

     
    105105LIBS+=xyssl 
    106106endif 
    107107 
     108ifeq ($(strip $(FREETZ_LIB_libpolarssl)),y) 
     109LIBS+=polarssl 
     110endif 
     111 
    108112ifeq ($(strip $(FREETZ_LIB_libusb)),y) 
    109113LIBS+=libusb 
    110114endif 
  • make/libs/patches/020-shared.polarssl.patch

     
     1--- library/Makefile 
     2+++ library/Makefile 
     3@@ -17,6 +17,11 @@ 
     4 # OSX shared library extension: 
     5 # DLEXT=dylib 
     6  
     7+VERSION=0.12.1 
     8+LIB_SO=libpolarssl.$(DLEXT) 
     9+LIB_SO_VERSION=$(LIB_SO).$(VERSION) 
     10+LIB_SO_MAJOR=$(LIB_SO).$(firstword $(subst ., ,$(VERSION))) 
     11+ 
     12 OBJS=  aes.o           arc4.o          base64.o        \ 
     13        bignum.o        certs.o         debug.o         \ 
     14        des.o           dhm.o           havege.o        \ 
     15@@ -33,7 +38,7 @@ 
     16  
     17 static: libpolarssl.a 
     18  
     19-shared: libpolarssl.$(DLEXT) 
     20+shared: $(LIB_SO_VERSION) 
     21  
     22 libpolarssl.a: $(OBJS) 
     23        echo "  AR    $@" 
     24@@ -41,9 +46,11 @@ 
     25        echo "  RL    $@" 
     26        ranlib $@ 
     27  
     28-libpolarssl.so: libpolarssl.a 
     29+$(LIB_SO_VERSION): $(OBJS) 
     30        echo "  LD    $@" 
     31-       $(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS) 
     32+       $(CC) -shared -Wl,-soname,$(LIB_SO_MAJOR) -o $@ $(OBJS) \ 
     33+       && ln -fs $@ $(LIB_SO_MAJOR) \ 
     34+       && ln -fs $(LIB_SO_MAJOR) $(LIB_SO) 
     35  
     36 libpolarssl.dylib: libpolarssl.a 
     37        echo "  LD    $@" 
  • make/libs/patches/030-do_not_omit_last_cert_in_chain.polarssl.patch

     
     1--- library/debug.c 
     2+++ library/debug.c 
     3@@ -182,7 +182,7 @@ 
     4     prefix[maxlen] = '\0'; 
     5     maxlen = sizeof( str ) - 1; 
     6  
     7-    while( crt != NULL && crt->next != NULL ) 
     8+    while( crt != NULL ) 
     9     { 
     10         char buf[1024]; 
     11         x509parse_cert_info( buf, sizeof( buf ) - 1, prefix, crt ); 
     12--- library/ssl_srv.c 
     13+++ library/ssl_srv.c 
     14@@ -485,7 +485,7 @@ 
     15     p += 2; 
     16     crt = ssl->ca_chain; 
     17  
     18-    while( crt != NULL && crt->next != NULL ) 
     19+    while( crt != NULL ) 
     20     { 
     21         if( p - buf > 4096 ) 
     22             break; 
     23--- library/ssl_tls.c 
     24+++ library/ssl_tls.c 
     25@@ -1160,7 +1160,7 @@ 
     26     i = 7; 
     27     crt = ssl->own_cert; 
     28  
     29-    while( crt != NULL && crt->next != NULL ) 
     30+    while( crt != NULL ) 
     31     { 
     32         n = crt->raw.len; 
     33         if( i + 3 + n > SSL_MAX_CONTENT_LEN ) 
  • make/libs/patches/010-config.polarssl.patch

     
     1--- include/polarssl/config.h 
     2+++ include/polarssl/config.h 
     3@@ -71,12 +71,12 @@ 
     4 /* 
     5  * Enable all SSL/TLS debugging messages. 
     6  */ 
     7-#define POLARSSL_DEBUG_MSG 
     8+/* #define POLARSSL_DEBUG_MSG */ 
     9  
     10 /* 
     11  * Enable the checkup functions (*_self_test). 
     12  */ 
     13-#define POLARSSL_SELF_TEST 
     14+/* #define POLARSSL_SELF_TEST */ 
     15  
     16 /* 
     17  * Enable the prime-number generation code. 
     18@@ -156,7 +156,7 @@ 
     19  * 
     20  * This module provides debugging functions. 
     21  */ 
     22-#define POLARSSL_DEBUG_C 
     23+/* #define POLARSSL_DEBUG_C */ 
     24  
     25 /* 
     26  * Module:  library/des.c 
     27@@ -229,7 +229,7 @@ 
     28  * 
     29  * This modules adds support for the VIA PadLock on x86. 
     30  */ 
     31-#define POLARSSL_PADLOCK_C 
     32+/* #define POLARSSL_PADLOCK_C */ 
     33  
     34 /* 
     35  * Module:  library/rsa.c 
  • make/libs/patches/001-x509write.polarssl.patch

     
     1--- include/polarssl/x509.h 
     2+++ include/polarssl/x509.h 
     3@@ -429,6 +429,229 @@ 
     4  */ 
     5 int x509_self_test( int verbose ); 
     6  
     7+/** 
     8+ * \brief          Write a certificate info file 
     9+ * 
     10+ * \param chain    points to the raw certificate data 
     11+ * \param path     filename to write the certificate to 
     12+ * \param format   X509_OUTPUT_DER or X509_OUTPUT_PEM 
     13+ * 
     14+ * \return         0 if successful, or a specific X509 error code 
     15+ */ 
     16+int x509write_crtfile( x509_raw *chain, 
     17+                       unsigned char *path, 
     18+                       int format ); 
     19+ 
     20+/** 
     21+ * \brief          Write a certificate signing request message format file 
     22+ * 
     23+ * \param chain    points to the raw certificate (with x509write_create_csr) data 
     24+ * \param path     filename to write the certificate to 
     25+ * \param format   X509_OUTPUT_DER or X509_OUTPUT_PEM 
     26+ * 
     27+ * \return         0 if successful, or a specific X509 error code 
     28+ */ 
     29+int x509write_csrfile( x509_raw *chain, 
     30+                       unsigned char *path, 
     31+                       int format ); 
     32+ 
     33+/* 
     34+ * \brief          Write a private RSA key into a file 
     35+ * 
     36+ * \param rsa      points to an RSA key 
     37+ * \param path     filename to write the key to 
     38+ * \param format   X509_OUTPUT_DER or X509_OUTPUT_PEM 
     39+ * 
     40+ * \return         0 if successful, or a specific X509 error code 
     41+ */ 
     42+int x509write_keyfile( rsa_context *rsa, 
     43+                       char *path, 
     44+                       int format ); 
     45+ 
     46+/** 
     47+ * \brief          Add a public key to certificate 
     48+ * 
     49+ * \param chain    points to the raw certificate data 
     50+ * \param pubkey   points to an RSA key 
     51+ * 
     52+ * \return         0 if successful, or a specific X509 error code 
     53+ */ 
     54+int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey ); 
     55+ 
     56+/** 
     57+ * \brief          Create x509 subject/issuer field to raw certificate 
     58+ *                 from string or CA cert. Make string NULL if you will 
     59+ *                 use the CA copy function or make CA NULL then used 
     60+ *                 the string parse. 
     61+ * 
     62+ * \param chain    points to the raw certificate data 
     63+ * \param names    a string that can hold (separete with ";"): 
     64+ *                     CN=CommonName 
     65+ *                 --   O=Organization 
     66+ *                 --  OU=OrgUnit 
     67+ *                 --  ST=State 
     68+ *                 --   L=Locality 
     69+ *                 --   R=Email 
     70+ *                 --   C=Country 
     71+ *                 . Make that NULL if you didn't need that. 
     72+ * \param flag     flag is X509_ISSUER or X509_SUBJECT that defined 
     73+ *                 where change 
     74+ * \param ca       the certificate for copy data. Make that NULL if you 
     75+ *                 didn't need that. 
     76+ * \param ca_flag  set the ca field from copy to crt 
     77+ * 
     78+ * \return         0 if successful, or a specific X509 error code 
     79+ */ 
     80+int x509write_add_customize ( x509_raw *crt, 
     81+                          unsigned char *names, 
     82+                          int flag, 
     83+                          x509_cert *ca, 
     84+                          int ca_flag ); 
     85+ 
     86+/** 
     87+* \brief          Add x509 issuer field 
     88+* 
     89+* \param chain    points to the raw certificate data 
     90+* \param issuer   a string holding (separete with ";"): 
     91+*                     CN=CommonName 
     92+*                 --   O=Organization 
     93+*                 --  OU=OrgUnit 
     94+*                 --  ST=State 
     95+*                 --   L=Locality 
     96+*                 --   R=Email 
     97+*                 --   C=Country 
     98+*                 . Set this to NULL if not needed. 
     99+* \return         0 if successful, or a specific X509 error code 
     100+*/ 
     101+int x509write_add_issuer( x509_raw *crt, unsigned char *issuer); 
     102+ 
     103+/** 
     104+ * \brief          Add x509 subject field 
     105+ * 
     106+ * \param chain    points to the raw certificate data 
     107+ * \param subject  a string holding (separete with ";"): 
     108+ *                     CN=CommonName 
     109+ *                 --   O=Organization 
     110+ *                 --  OU=OrgUnit 
     111+ *                 --  ST=State 
     112+ *                 --   L=Locality 
     113+ *                 --   R=Email 
     114+ *                 --   C=Country 
     115+ *                 . Set this to NULL if not needed. 
     116+ * \return         0 if successful, or a specific X509 error code 
     117+ */ 
     118+int x509write_add_subject( x509_raw *crt, unsigned char *subject); 
     119+ 
     120+/** 
     121+* \brief          Copy x509 issuer field from another certificate 
     122+* 
     123+* \param chain    points to the raw certificate data 
     124+* \param from_crt the certificate whose issuer is to be copied. 
     125+* \return         0 if successful, or a specific X509 error code 
     126+*/ 
     127+int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt); 
     128+ 
     129+/** 
     130+* \brief          Copy x509 subject field from another certificate 
     131+* 
     132+* \param chain    points to the raw certificate data 
     133+* \param from_crt the certificate whose subject is to be copied. 
     134+* \return         0 if successful, or a specific X509 error code 
     135+*/ 
     136+int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt); 
     137+ 
     138+/** 
     139+* \brief          Copy x509 issuer field from the subject of another certificate 
     140+* 
     141+* \param chain    points to the raw certificate data 
     142+* \param from_crt the certificate whose subject is to be copied. 
     143+* \return         0 if successful, or a specific X509 error code 
     144+*/ 
     145+int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt); 
     146+ 
     147+/** 
     148+* \brief          Copy x509 subject field from the issuer of another certificate 
     149+* 
     150+* \param chain    points to the raw certificate data 
     151+* \param from_crt the certificate whose issuer is to be copied. 
     152+* \return         0 if successful, or a specific X509 error code 
     153+*/ 
     154+int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt); 
     155+ 
     156+/** 
     157+ * \brief          Create x509 validity time in UTC 
     158+ * 
     159+ * \param chain    points to the raw certificate data 
     160+ * \param before   valid not before in format YYYY-MM-DD hh:mm:ss 
     161+ * \param after    valid not after  in format YYYY-MM-DD hh:mm:ss 
     162+ * 
     163+ * \return         0 if successful, or a specific X509 error code 
     164+ */ 
     165+int x509write_add_validity( x509_raw *crt, 
     166+                               unsigned char *before, 
     167+                               unsigned char *after ); 
     168+ 
     169+/** 
     170+ * \brief          Create a self-signed certificate 
     171+ * 
     172+ * \param chain    points to the raw certificate data 
     173+ * \param rsa      a private key to sign the certificate 
     174+ * 
     175+ * \return         0 if successful, or a specific X509 error code 
     176+ */ 
     177+int x509write_create_selfsign( x509_raw *crt, rsa_context *raw ); 
     178+ 
     179+/** 
     180+ * \brief          Create a certificate 
     181+ * 
     182+ * \param chain    points to the raw certificate data 
     183+ * \param rsa      a private key to sign the certificate 
     184+ * 
     185+ * \return         0 if successful, or a specific X509 error code 
     186+ */ 
     187+int x509write_create_sign( x509_raw *crt, rsa_context *raw ); 
     188+ 
     189+/** 
     190+ * \brief          Create a certificate signing request 
     191+ * 
     192+ * \param chain    points to the raw certificate data. Didn't use the 
     193+ *                 same chain that u have use for certificate. 
     194+ * \param privkey  a rsa private key 
     195+ * 
     196+ * \return         0 if successful, or a specific X509 error code 
     197+ */ 
     198+int x509write_create_csr( x509_raw *chain, rsa_context *privkey ); 
     199+ 
     200+/** 
     201+ * \brief           Serialize an rsa key into DER 
     202+ * 
     203+ * \param rsa       a rsa key for output 
     204+ * \param node      a x509 node for write into 
     205+ * 
     206+ * \return          0 if successful, or a specific X509 error code 
     207+ */ 
     208+int x509write_serialize_key( rsa_context *rsa, x509_node *node ); 
     209+ 
     210+/** 
     211+ * \brief          Unallocate all raw certificate data 
     212+ */ 
     213+void x509write_free_raw( x509_raw *crt ); 
     214+ 
     215+/** 
     216+ * \brief          Allocate all raw certificate data 
     217+ */ 
     218+void x509write_init_raw( x509_raw *crt ); 
     219+ 
     220+/** 
     221+ * \brief          Unallocate all node certificate data 
     222+ */ 
     223+void x509write_free_node( x509_node *crt_node ); 
     224+ 
     225+/** 
     226+ * \brief          Allocate all node certificate data 
     227+ */ 
     228+void x509write_init_node( x509_node *crt_node ); 
     229+ 
     230 #ifdef __cplusplus 
     231 } 
     232 #endif 
     233--- library/Makefile 
     234+++ library/Makefile 
     235@@ -25,7 +25,7 @@ 
     236        sha1.o          sha2.o          sha4.o          \ 
     237        ssl_cli.o       ssl_srv.o       ssl_tls.o       \ 
     238        timing.o        x509parse.o     xtea.o          \ 
     239-       camellia.o 
     240+       camellia.o      x509write.o 
     241  
     242 .SILENT: 
     243  
     244--- library/x509write.c 
     245+++ library/x509write.c 
     246@@ -0,0 +1,1135 @@ 
     247+/* 
     248+ *  X.509 certificate and private key writing 
     249+ * 
     250+ *  Copyright (C) 2006-2007  Pascal Vizeli <pvizeli@yahoo.de> 
     251+ *  Modifications (C) 2009 Steven Barth <steven@midlink.org> 
     252+ * 
     253+ *  This library is free software; you can redistribute it and/or 
     254+ *  modify it under the terms of the GNU Lesser General Public 
     255+ *  License, version 2.1 as published by the Free Software Foundation. 
     256+ * 
     257+ *  This library is distributed in the hope that it will be useful, 
     258+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
     259+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     260+ *  Lesser General Public License for more details. 
     261+ * 
     262+ *  You should have received a copy of the GNU Lesser General Public 
     263+ *  License along with this library; if not, write to the Free Software 
     264+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
     265+ *  MA  02110-1301  USA 
     266+ */ 
     267+/* 
     268+ *  The ITU-T X.509 standard defines a certificat format for PKI. 
     269+ * 
     270+ *  http://www.ietf.org/rfc/rfc2459.txt 
     271+ *  http://www.ietf.org/rfc/rfc3279.txt 
     272+ * 
     273+ *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc 
     274+ * 
     275+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 
     276+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 
     277+ * 
     278+ *  For CRS: 
     279+ *  http://www.faqs.org/rfcs/rfc2314.html 
     280+ */ 
     281+#include "polarssl/config.h" 
     282+#include "polarssl/x509.h" 
     283+#include "polarssl/base64.h" 
     284+#include "polarssl/sha1.h" 
     285+ 
     286+#include <string.h> 
     287+#include <stdlib.h> 
     288+#include <stdio.h> 
     289+#include <stdarg.h> 
     290+#include <time.h> 
     291+ 
     292+#define and && 
     293+#define or || 
     294+ 
     295+#if defined _MSC_VER && !defined snprintf 
     296+#define snprintf _snprintf 
     297+#endif 
     298+ 
     299+static int x509write_realloc_node(x509_node *node, size_t larger); 
     300+static int x509write_file(x509_node *node, char *path, int format, const char* pem_prolog, const char* pem_epilog); 
     301+ 
     302+/* 
     303+ * evaluate how mani octet have this integer 
     304+ */ 
     305+static int asn1_eval_octet(unsigned int digit) 
     306+{ 
     307+    int i, byte; 
     308+ 
     309+    for (byte = 4, i = 24; i >= 0; i -= 8, --byte) 
     310+        if (((digit >> i) & 0xFF) != 0) 
     311+            return byte; 
     312+ 
     313+    return 0; 
     314+} 
     315+ 
     316+/* 
     317+ * write the asn.1 lenght form into p 
     318+ */ 
     319+static int asn1_add_len(unsigned int size, x509_node *node) 
     320+{ 
     321+    if (size > 127) { 
     322+ 
     323+        /* long size */ 
     324+        int byte = asn1_eval_octet(size); 
     325+        int i = 0; 
     326+ 
     327+        *(node->p) = (0x80 | byte) & 0xFF; 
     328+        ++node->p; 
     329+ 
     330+        for (i = byte; i > 0; --i) { 
     331+ 
     332+            *(node->p) = (size >> ((i - 1) * 8)) & 0xFF; 
     333+            ++node->p; 
     334+        } 
     335+ 
     336+    } else { 
     337+ 
     338+        /* short size */ 
     339+        *(node->p) = size & 0xFF; 
     340+        if (size != 0) 
     341+            ++node->p; 
     342+    } 
     343+ 
     344+    return 0; 
     345+} 
     346+ 
     347+/* 
     348+ * write a ans.1 object into p 
     349+ */ 
     350+static int asn1_add_obj(unsigned char *value, unsigned int size, int tag, 
     351+        x509_node *node) 
     352+{ 
     353+    int tl = 2; 
     354+ 
     355+    if (tag == ASN1_BIT_STRING) 
     356+        ++tl; 
     357+ 
     358+    if (size > 127) 
     359+        x509write_realloc_node(node, (size_t) size + tl + 
     360+                asn1_eval_octet(size)); 
     361+    else 
     362+        x509write_realloc_node(node, (size_t) size + tl); 
     363+ 
     364+    if (node->data == NULL) 
     365+        return 1; 
     366+ 
     367+    /* tag */ 
     368+    *(node->p) = tag & 0xFF; 
     369+    ++node->p; 
     370+ 
     371+    /* len */ 
     372+    if (tag == ASN1_BIT_STRING) { 
     373+        asn1_add_len((unsigned int) size + 1, node); 
     374+        *(node->p) = 0x00; 
     375+        ++node->p; 
     376+    } else { 
     377+        asn1_add_len((unsigned int) size, node); 
     378+    } 
     379+ 
     380+    /* value */ 
     381+    if (size > 0) { 
     382+ 
     383+        memcpy(node->p, value, (size_t) size); 
     384+        if ((node->p += size -1) != node->end) 
     385+            return POLARSSL_ERR_X509_POINT_ERROR; 
     386+    } else { 
     387+        /* make nothing -> NULL */ 
     388+    } 
     389+ 
     390+    return 0; 
     391+} 
     392+ 
     393+/* 
     394+ * write a asn.1 conform integer object 
     395+ */ 
     396+static int asn1_add_int(signed int value, x509_node *node) 
     397+{ 
     398+    signed int i = 0, neg = 1; 
     399+    unsigned int byte, u_val = 0, tmp_val = 0; 
     400+ 
     401+    /* if negate? */ 
     402+    if (value < 0) { 
     403+        neg = -1; 
     404+        u_val = ~value; 
     405+    } else { 
     406+        u_val = value; 
     407+    } 
     408+ 
     409+    byte = asn1_eval_octet(u_val); 
     410+    /* 0 isn't NULL */ 
     411+    if (byte == 0) 
     412+        byte = 1; 
     413+ 
     414+    /* ASN.1 integer is signed! */ 
     415+    if (byte < 4 and ((u_val >> ((byte -1) * 8)) & 0xFF) == 0x80) 
     416+        byte += 1; 
     417+ 
     418+    if (x509write_realloc_node(node, (size_t) byte + 2) != 0) 
     419+        return 1; 
     420+ 
     421+    /* tag */ 
     422+    *(node->p) = ASN1_INTEGER; 
     423+    ++node->p; 
     424+ 
     425+    /* len */ 
     426+    asn1_add_len(byte, node); 
     427+ 
     428+    /* value */ 
     429+    for (i = byte; i > 0; --i) { 
     430+ 
     431+        tmp_val = (u_val >> ((i - 1) * 8)) & 0xFF; 
     432+        if (neg == 1) 
     433+            *(node->p) = tmp_val; 
     434+        else 
     435+            *(node->p) = ~tmp_val; 
     436+ 
     437+        if (i > 1) 
     438+          ++node->p; 
     439+    } 
     440+ 
     441+    if (node->p != node->end) 
     442+        return POLARSSL_ERR_X509_POINT_ERROR; 
     443+ 
     444+    return 0; 
     445+} 
     446+ 
     447+/* 
     448+ * write a asn.1 conform mpi object 
     449+ */ 
     450+static int asn1_add_mpi(mpi *value, int tag, x509_node *node) 
     451+{ 
     452+    size_t size = (mpi_msb(value) / 8) + 1; 
     453+    unsigned char *buf; 
     454+    int buf_len = (int) size, tl = 2; 
     455+ 
     456+    if (tag == ASN1_BIT_STRING) 
     457+        ++tl; 
     458+ 
     459+    if (size > 127) 
     460+        x509write_realloc_node(node, size + (size_t) tl + 
     461+            asn1_eval_octet((unsigned int)size)); 
     462+    else 
     463+        x509write_realloc_node(node, size + (size_t) tl); 
     464+ 
     465+    if (node->data == NULL) 
     466+        return 1; 
     467+ 
     468+    buf = (unsigned char*) malloc(size); 
     469+    if (mpi_write_binary(value, buf, buf_len) != 0) 
     470+        return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL; 
     471+ 
     472+    /* tag */ 
     473+    *(node->p) = tag & 0xFF; 
     474+    ++node->p; 
     475+ 
     476+    /* len */ 
     477+    if (tag == ASN1_BIT_STRING) { 
     478+        asn1_add_len((unsigned int) size + 1, node); 
     479+        *(node->p) = 0x00; 
     480+        ++node->p; 
     481+    } else { 
     482+        asn1_add_len((unsigned int) size, node); 
     483+    } 
     484+ 
     485+    /* value */ 
     486+    memcpy(node->p, buf, size); 
     487+    free(buf); 
     488+ 
     489+    if ((node->p += (int) size -1) != node->end) 
     490+        return POLARSSL_ERR_X509_POINT_ERROR; 
     491+ 
     492+    return 0; 
     493+} 
     494+ 
     495+/* 
     496+ * write a node into asn.1 conform object 
     497+ */ 
     498+static int asn1_append_tag(x509_node *node, int tag) 
     499+{ 
     500+    int tl = 2; 
     501+ 
     502+    x509_node tmp; 
     503+    x509write_init_node(&tmp); 
     504+ 
     505+    if (tag == ASN1_BIT_STRING) 
     506+        ++tl; 
     507+ 
     508+    if (node->len > 127) 
     509+        x509write_realloc_node(&tmp, node->len + (size_t) tl + 
     510+            asn1_eval_octet((unsigned int)node->len)); 
     511+    else 
     512+        x509write_realloc_node(&tmp, node->len + (size_t) tl); 
     513+ 
     514+    if (tmp.data == NULL) { 
     515+        x509write_free_node(&tmp); 
     516+        return 1; 
     517+    } 
     518+ 
     519+    /* tag */ 
     520+    *(tmp.p) = tag & 0xFF; 
     521+    ++tmp.p; 
     522+ 
     523+    /* len */ 
     524+    if (tag == ASN1_BIT_STRING) { 
     525+        asn1_add_len((unsigned int) node->len + 1, &tmp); 
     526+        *(tmp.p) = 0x00; 
     527+        ++tmp.p; 
     528+    } else { 
     529+        asn1_add_len((unsigned int) node->len, &tmp); 
     530+    } 
     531+ 
     532+    /* value */ 
     533+    memcpy(tmp.p, node->data, node->len); 
     534+ 
     535+    /* good? */ 
     536+    if ((tmp.p += (int) node->len -1) != tmp.end) { 
     537+        x509write_free_node(&tmp); 
     538+        return POLARSSL_ERR_X509_POINT_ERROR; 
     539+    } 
     540+ 
     541+    free(node->data); 
     542+    node->data = tmp.data; 
     543+    node->p = tmp.p; 
     544+    node->end = tmp.end; 
     545+    node->len = tmp.len; 
     546+ 
     547+    return 0; 
     548+} 
     549+ 
     550+/* 
     551+ * write nodes into a asn.1 object 
     552+ */ 
     553+static int asn1_append_nodes(x509_node *node, int tag, int anz, ...) 
     554+{ 
     555+    va_list ap; 
     556+    size_t size = 0; 
     557+    x509_node *tmp; 
     558+    int count; 
     559+ 
     560+    va_start(ap, anz); 
     561+    count = anz; 
     562+ 
     563+    while (count--) { 
     564+ 
     565+        tmp = va_arg(ap, x509_node*); 
     566+        if (tmp->data != NULL) 
     567+            size += tmp->len; 
     568+    } 
     569+ 
     570+    if ( size > 127) { 
     571+        if (x509write_realloc_node(node, size + (size_t) 2 + 
     572+                    asn1_eval_octet(size)) != 0) 
     573+            return 1; 
     574+    } else { 
     575+        if (x509write_realloc_node(node, size + (size_t) 2) != 0) 
     576+            return 1; 
     577+    } 
     578+ 
     579+    /* tag */ 
     580+    *(node->p) = tag & 0xFF; 
     581+    ++node->p; 
     582+ 
     583+    /* len */ 
     584+    asn1_add_len(size, node); 
     585+ 
     586+    /* value */ 
     587+    va_start(ap, anz); 
     588+    count = anz; 
     589+ 
     590+    while (count--) { 
     591+ 
     592+        tmp = va_arg(ap, x509_node*); 
     593+        if (tmp->data != NULL) { 
     594+ 
     595+            memcpy(node->p, tmp->data, tmp->len); 
     596+            if ((node->p += (int) tmp->len -1) != node->end) 
     597+                ++node->p; 
     598+        } 
     599+    } 
     600+ 
     601+    va_end(ap); 
     602+    return 0; 
     603+} 
     604+ 
     605+/* 
     606+ * write a ASN.1 conform object identifiere include a "tag" 
     607+ */ 
     608+static int asn1_add_oid(x509_node *node, unsigned char *oid, size_t len, 
     609+        int tag, int tag_val, unsigned char *value, size_t val_len) 
     610+{ 
     611+    int ret; 
     612+    x509_node tmp; 
     613+ 
     614+    x509write_init_node(&tmp); 
     615+ 
     616+    /* OBJECT IDENTIFIER */ 
     617+    if ((ret = asn1_add_obj(oid, len, ASN1_OID, &tmp)) != 0) { 
     618+        x509write_free_node(&tmp); 
     619+        return ret; 
     620+    } 
     621+ 
     622+    /* value */ 
     623+    if ((ret = asn1_add_obj(value, val_len, tag_val, &tmp)) != 0) { 
     624+        x509write_free_node(&tmp); 
     625+        return ret; 
     626+    } 
     627+ 
     628+    /* SET/SEQUENCE */ 
     629+    if ((ret = asn1_append_nodes(node, tag, 1, &tmp)) != 0) { 
     630+        x509write_free_node(&tmp); 
     631+        return ret; 
     632+    } 
     633+ 
     634+    x509write_free_node(&tmp); 
     635+    return 0; 
     636+} 
     637+ 
     638+/* 
     639+ *  utcTime        UTCTime 
     640+ */ 
     641+static int asn1_add_date_utc(unsigned char *time, x509_node *node) 
     642+{ 
     643+    unsigned char date[13], *sp; 
     644+    x509_time xtime; 
     645+    int ret; 
     646+ 
     647+    sscanf((char*)time, "%d-%d-%d %d:%d:%d", &xtime.year, &xtime.mon, 
     648+       &xtime.day, &xtime.hour, &xtime.min, &xtime.sec); 
     649+ 
     650+    /* convert to YY */ 
     651+    if (xtime.year > 2000) 
     652+        xtime.year -= 2000; 
     653+    else 
     654+        xtime.year -= 1900; 
     655+ 
     656+    snprintf((char*)date, 13, "%2d%2d%2d%2d%2d%2d", xtime.year, xtime.mon, xtime.day, 
     657+        xtime.hour, xtime.min, xtime.sec); 
     658+ 
     659+    /* replace ' ' to '0' */ 
     660+    for (sp = date; *sp != '\0'; ++sp) 
     661+        if (*sp == '\x20') 
     662+            *sp = '\x30'; 
     663+ 
     664+    date[12] = 'Z'; 
     665+ 
     666+    if ((ret = asn1_add_obj(date, 13, ASN1_UTC_TIME, node)) != 0) 
     667+        return ret; 
     668+ 
     669+    return 0; 
     670+} 
     671+ 
     672+/* 
     673+ * serialize an rsa key into DER 
     674+ */ 
     675+ 
     676+int x509write_serialize_key(rsa_context *rsa, x509_node *node) 
     677+{ 
     678+    int ret = 0; 
     679+    x509write_init_node(node); 
     680+ 
     681+    /* vers, n, e, d, p, q, dp, dq, pq */ 
     682+    if ((ret = asn1_add_int(rsa->ver, node)) != 0) 
     683+        return ret; 
     684+    if ((ret = asn1_add_mpi(&rsa->N, ASN1_INTEGER, node)) != 0) 
     685+        return ret; 
     686+    if ((ret = asn1_add_mpi(&rsa->E, ASN1_INTEGER, node)) != 0) 
     687+        return ret; 
     688+    if ((ret = asn1_add_mpi(&rsa->D, ASN1_INTEGER, node)) != 0) 
     689+        return ret; 
     690+    if ((ret = asn1_add_mpi(&rsa->P, ASN1_INTEGER, node)) != 0) 
     691+        return ret; 
     692+    if ((ret = asn1_add_mpi(&rsa->Q, ASN1_INTEGER, node)) != 0) 
     693+        return ret; 
     694+    if ((ret = asn1_add_mpi(&rsa->DP, ASN1_INTEGER, node)) != 0) 
     695+        return ret; 
     696+    if ((ret = asn1_add_mpi(&rsa->DQ, ASN1_INTEGER, node)) != 0) 
     697+        return ret; 
     698+    if ((ret = asn1_add_mpi(&rsa->QP, ASN1_INTEGER, node)) != 0) 
     699+        return ret; 
     700+    if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) 
     701+        return ret; 
     702+ 
     703+    return 0; 
     704+} 
     705+ 
     706+/* 
     707+ * write a der/pem encoded rsa private key into a file 
     708+ */ 
     709+int x509write_keyfile(rsa_context *rsa, char *path, int out_flag) 
     710+{ 
     711+    int ret = 0; 
     712+    const char key_beg[] = "-----BEGIN RSA PRIVATE KEY-----\n", 
     713+                key_end[] = "-----END RSA PRIVATE KEY-----\n"; 
     714+    x509_node node; 
     715+ 
     716+    x509write_init_node(&node); 
     717+    if ((ret = x509write_serialize_key(rsa,&node)) != 0) { 
     718+        x509write_free_node(&node); 
     719+             return ret; 
     720+    } 
     721+ 
     722+    ret = x509write_file(&node,path,out_flag,key_beg,key_end); 
     723+    x509write_free_node(&node); 
     724+ 
     725+    return ret; 
     726+} 
     727+ 
     728+ 
     729+/* 
     730+ * reasize the memory for node 
     731+ */ 
     732+static int x509write_realloc_node(x509_node *node, size_t larger) 
     733+{ 
     734+    /* init len */ 
     735+    if (node->data == NULL) { 
     736+        node->len = 0; 
     737+        node->data = malloc(larger); 
     738+        if(node->data == NULL) 
     739+            return 1; 
     740+    } else { 
     741+        /* realloc memory */ 
     742+        if ((node->data = realloc(node->data, node->len + larger)) == NULL) 
     743+            return 1; 
     744+    } 
     745+ 
     746+    /* init pointer */ 
     747+    node->p = &node->data[node->len]; 
     748+    node->len += larger; 
     749+    node->end = &node->data[node->len -1]; 
     750+ 
     751+    return 0; 
     752+} 
     753+ 
     754+/* 
     755+ * init node 
     756+ */ 
     757+void x509write_init_node(x509_node *node) 
     758+{ 
     759+    memset(node, 0, sizeof(x509_node)); 
     760+} 
     761+ 
     762+/* 
     763+ * clean memory 
     764+ */ 
     765+void x509write_free_node(x509_node *node) 
     766+{ 
     767+    if (node->data != NULL) 
     768+        free(node->data); 
     769+    node->p = NULL; 
     770+    node->end = NULL; 
     771+    node->len = 0; 
     772+} 
     773+ 
     774+/* 
     775+ * write a x509 certificate into file 
     776+ */ 
     777+int x509write_crtfile(x509_raw *chain, unsigned char *path, int out_flag) 
     778+{ 
     779+    const char cer_beg[] = "-----BEGIN CERTIFICATE-----\n", 
     780+               cer_end[] = "-----END CERTIFICATE-----\n"; 
     781+ 
     782+    return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); 
     783+} 
     784+ 
     785+/* 
     786+ * write a x509 certificate into file 
     787+ */ 
     788+int x509write_csrfile(x509_raw *chain, unsigned char *path, int out_flag) 
     789+{ 
     790+    const char cer_beg[] = "-----BEGIN CERTIFICATE REQUEST-----\n", 
     791+               cer_end[] = "-----END CERTIFICATE REQUEST-----\n"; 
     792+ 
     793+    return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end); 
     794+} 
     795+ 
     796+/* 
     797+ * write an x509 file 
     798+ */ 
     799+static int x509write_file(x509_node *node, char *path, int format, 
     800+        const char* pem_prolog, const char* pem_epilog) 
     801+{ 
     802+    FILE *ofstream; 
     803+    int is_err = 1, buf_len, i, n; 
     804+    char* base_buf; 
     805+ 
     806+    if ((ofstream = fopen(path, "wb")) == NULL) 
     807+        return 1; 
     808+ 
     809+    switch (format) { 
     810+        case X509_OUTPUT_DER: 
     811+            if (fwrite(node->data, 1, node->len, ofstream) 
     812+                != node->len) 
     813+                is_err = -1; 
     814+            break; 
     815+        case X509_OUTPUT_PEM: 
     816+            if (fprintf(ofstream,pem_prolog)<0) { 
     817+                is_err = -1; 
     818+                break; 
     819+            } 
     820+ 
     821+            buf_len = node->len << 1; 
     822+            base_buf = (char*) malloc((size_t)buf_len); 
     823+            memset(base_buf,0,buf_len); 
     824+            if (base64_encode(base_buf, &buf_len, node->data, 
     825+                        (int) node->len) != 0) { 
     826+                is_err = -1; 
     827+                break; 
     828+            } 
     829+ 
     830+            n=strlen(base_buf); 
     831+            for(i=0;i<n;i+=64) { 
     832+                fprintf(ofstream,"%.64s\n",&base_buf[i]); 
     833+            } 
     834+ 
     835+            if (fprintf(ofstream, pem_epilog)<0) { 
     836+                is_err = -1; 
     837+                break; 
     838+            } 
     839+ 
     840+            free(base_buf); 
     841+    } 
     842+ 
     843+    fclose(ofstream); 
     844+ 
     845+    if (is_err == -1) 
     846+        return 1; 
     847+ 
     848+    return 0; 
     849+} 
     850+ 
     851+ 
     852+/* 
     853+ * add the owner public key to x509 certificate 
     854+ */ 
     855+int x509write_add_pubkey(x509_raw *chain, rsa_context *pubkey) 
     856+{ 
     857+    x509_node n_tmp, n_tmp2, *node; 
     858+    int ret; 
     859+ 
     860+    node = &chain->subpubkey; 
     861+ 
     862+    x509write_init_node(&n_tmp); 
     863+    x509write_init_node(&n_tmp2); 
     864+ 
     865+    /* 
     866+    *  RSAPublicKey ::= SEQUENCE { 
     867+    *      modulus           INTEGER,  -- n 
     868+    *      publicExponent    INTEGER   -- e 
     869+    *  } 
     870+    */ 
     871+    if ((ret = asn1_add_mpi(&pubkey->N, ASN1_INTEGER, &n_tmp)) != 0) { 
     872+        x509write_free_node(&n_tmp); 
     873+        x509write_free_node(&n_tmp2); 
     874+        return ret; 
     875+    } 
     876+    if ((ret = asn1_add_mpi(&pubkey->E, ASN1_INTEGER, &n_tmp)) != 0) { 
     877+        x509write_free_node(&n_tmp); 
     878+        x509write_free_node(&n_tmp2); 
     879+        return ret; 
     880+    } 
     881+    if ((ret = asn1_append_tag(&n_tmp, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) 
     882+            != 0) { 
     883+        x509write_free_node(&n_tmp); 
     884+        x509write_free_node(&n_tmp2); 
     885+        return ret; 
     886+    } 
     887+ 
     888+    /* 
     889+     *  SubjectPublicKeyInfo  ::=  SEQUENCE  { 
     890+     *       algorithm            AlgorithmIdentifier, 
     891+     *       subjectPublicKey     BIT STRING } 
     892+     */ 
     893+    if ((ret = asn1_append_tag(&n_tmp, ASN1_BIT_STRING)) != 0) { 
     894+        x509write_free_node(&n_tmp); 
     895+        x509write_free_node(&n_tmp2); 
     896+       return ret; 
     897+    } 
     898+    if ((ret = asn1_add_oid(&n_tmp2, (unsigned char*)OID_PKCS1_RSA, 9, 
     899+                  ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, 
     900+                  (unsigned char *)"", 0)) != 0) { 
     901+        x509write_free_node(&n_tmp); 
     902+        x509write_free_node(&n_tmp2); 
     903+        return ret; 
     904+    } 
     905+ 
     906+    if ((ret = asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 2, 
     907+                   &n_tmp2, &n_tmp))) { 
     908+        x509write_free_node(&n_tmp); 
     909+        x509write_free_node(&n_tmp2); 
     910+        return ret; 
     911+    } 
     912+ 
     913+    x509write_free_node(&n_tmp); 
     914+    x509write_free_node(&n_tmp2); 
     915+    return 0; 
     916+} 
     917+ 
     918+/* 
     919+ *  RelativeDistinguishedName ::= 
     920+ *    SET OF AttributeTypeAndValue 
     921+ * 
     922+ *  AttributeTypeAndValue ::= SEQUENCE { 
     923+ *    type     AttributeType, 
     924+ *    value    AttributeValue } 
     925+ */ 
     926+static int x509write_add_name(x509_node *node, unsigned char *oid, 
     927+        unsigned int oid_len, unsigned char *value, int len, int value_tag) 
     928+{ 
     929+    int ret; 
     930+    x509_node n_tmp; 
     931+ 
     932+    x509write_init_node(&n_tmp); 
     933+ 
     934+    if ((ret = asn1_add_oid(&n_tmp, oid, oid_len, 
     935+                ASN1_CONSTRUCTED | ASN1_SEQUENCE, value_tag, 
     936+                value, len))) { 
     937+        x509write_free_node(&n_tmp); 
     938+        return ret; 
     939+    } 
     940+ 
     941+    if ((asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SET, 1, &n_tmp)) 
     942+            != 0) { 
     943+        x509write_free_node(&n_tmp); 
     944+        return ret; 
     945+    } 
     946+ 
     947+    x509write_free_node(&n_tmp); 
     948+    return 0; 
     949+} 
     950+ 
     951+/* 
     952+ * Parse the name string and add to node 
     953+ */ 
     954+static int x509write_parse_names(x509_node *node, unsigned char *names) 
     955+{ 
     956+    unsigned char *sp, *begin = NULL; 
     957+    unsigned char oid[3] = OID_X520, tag[4], *tag_sp = tag; 
     958+    unsigned char *C = NULL, *CN = NULL, *O = NULL, *OU = NULL, 
     959+                  *ST = NULL, *L = NULL, *R = NULL; 
     960+    int C_len = 0, CN_len = 0, O_len = 0, OU_len = 0, ST_len = 0, 
     961+               L_len = 0, R_len = 0; 
     962+    int ret = 0, is_tag = 1, is_begin = -1, len = 0; 
     963+ 
     964+ 
     965+    for (sp = names; ; ++sp) { 
     966+ 
     967+        /* filter tag */ 
     968+        if (is_tag == 1) { 
     969+ 
     970+            if (tag_sp == &tag[3]) 
     971+                return POLARSSL_ERR_X509_VALUE_TO_LENGTH; 
     972+ 
     973+            /* is tag end? */ 
     974+            if (*sp == '=') { 
     975+                is_tag = -1; 
     976+                *tag_sp = '\0'; 
     977+                is_begin = 1; 
     978+                /* set len 0 (reset) */ 
     979+                len = 0; 
     980+            } else { 
     981+                /* tag hasn't ' '! */ 
     982+                if (*sp != ' ') { 
     983+                    *tag_sp = *sp; 
     984+                    ++tag_sp; 
     985+                } 
     986+            } 
     987+        /* filter value */ 
     988+        } else { 
     989+ 
     990+            /* set pointer of value begin */ 
     991+            if (is_begin == 1) { 
     992+                begin = sp; 
     993+                is_begin = -1; 
     994+            } 
     995+ 
     996+            /* is value at end? */ 
     997+            if (*sp == ';' or *sp == '\0') { 
     998+                is_tag = 1; 
     999+ 
     1000+                /* common name */ 
     1001+                if (tag[0] == 'C' and tag[1] == 'N') { 
     1002+                    CN = begin; 
     1003+                    CN_len = len; 
     1004+ 
     1005+                /* organization */ 
     1006+                } else if (tag[0] == 'O' and tag[1] == '\0') { 
     1007+                    O = begin; 
     1008+                    O_len = len; 
     1009+ 
     1010+                /* country */ 
     1011+                } else if (tag[0] == 'C' and tag[1] == '\0') { 
     1012+                    C = begin; 
     1013+                    C_len = len; 
     1014+ 
     1015+                /* organisation unit */ 
     1016+                } else if (tag[0] == 'O' and tag[1] == 'U') { 
     1017+                    OU = begin; 
     1018+                    OU_len = len; 
     1019+ 
     1020+                /* state */ 
     1021+                } else if (tag[0] == 'S' and tag[1] == 'T') { 
     1022+                    ST = begin; 
     1023+                    ST_len = len; 
     1024+ 
     1025+                /* locality */ 
     1026+                } else if (tag[0] == 'L' and tag[1] == '\0') { 
     1027+                    L = begin; 
     1028+                    L_len = len; 
     1029+ 
     1030+                /* email */ 
     1031+                } else if (tag[0] == 'R' and tag[1] == '\0') { 
     1032+                    R = begin; 
     1033+                    R_len = len; 
     1034+                } 
     1035+ 
     1036+                /* set tag poiner to begin */ 
     1037+                tag_sp = tag; 
     1038+ 
     1039+                /* is at end? */ 
     1040+                if (*sp == '\0' or *(sp +1) == '\0') 
     1041+                    break; 
     1042+            } else { 
     1043+                ++len; 
     1044+            } 
     1045+        } 
     1046+ 
     1047+        /* make saver */ 
     1048+        if (*sp == '\0') 
     1049+          break; 
     1050+    } /* end for */ 
     1051+ 
     1052+    /* country */ 
     1053+    if (C != NULL) { 
     1054+        oid[2] = X520_COUNTRY; 
     1055+        if ((ret = x509write_add_name(node, oid, 3, C, C_len, 
     1056+                        ASN1_PRINTABLE_STRING)) != 0) 
     1057+            return ret; 
     1058+    } 
     1059+ 
     1060+    /* state */ 
     1061+    if (ST != NULL) { 
     1062+        oid[2] = X520_STATE; 
     1063+        if ((ret = x509write_add_name(node, oid, 3, ST, ST_len, 
     1064+                        ASN1_PRINTABLE_STRING)) != 0) 
     1065+            return ret; 
     1066+    } 
     1067+ 
     1068+    /* locality */ 
     1069+    if (L != NULL) { 
     1070+        oid[2] = X520_LOCALITY; 
     1071+        if ((ret = x509write_add_name(node, oid, 3, L, L_len, 
     1072+                        ASN1_PRINTABLE_STRING)) != 0) 
     1073+            return ret; 
     1074+    } 
     1075+ 
     1076+    /* organization */ 
     1077+    if (O != NULL) { 
     1078+        oid[2] = X520_ORGANIZATION; 
     1079+        if ((ret = x509write_add_name(node, oid, 3, O, O_len, 
     1080+                        ASN1_PRINTABLE_STRING)) != 0) 
     1081+            return ret; 
     1082+    } 
     1083+ 
     1084+    /* organisation unit */ 
     1085+    if (OU != NULL) { 
     1086+        oid[2] = X520_ORG_UNIT; 
     1087+        if ((ret = x509write_add_name(node, oid, 3, OU, OU_len, 
     1088+                        ASN1_PRINTABLE_STRING)) != 0) 
     1089+            return ret; 
     1090+    } 
     1091+ 
     1092+    /* common name */ 
     1093+    if (CN != NULL) { 
     1094+        oid[2] = X520_COMMON_NAME; 
     1095+        if ((ret = x509write_add_name(node, oid, 3, CN, CN_len, 
     1096+                        ASN1_PRINTABLE_STRING)) != 0) 
     1097+            return ret; 
     1098+    } 
     1099+ 
     1100+    /* email */ 
     1101+    if (R != NULL) { 
     1102+        if ((ret = x509write_add_name(node, (unsigned char*)OID_PKCS9_EMAIL, 
     1103+                       9, R, R_len, ASN1_IA5_STRING)) != 0) 
     1104+            return ret; 
     1105+    } 
     1106+ 
     1107+    if ((asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) 
     1108+        return ret; 
     1109+ 
     1110+    return 0; 
     1111+} 
     1112+ 
     1113+/* 
     1114+ * Copy raw data from orginal ca to node 
     1115+ */ 
     1116+static int x509write_copy_from_raw(x509_node *node, x509_buf *raw) 
     1117+{ 
     1118+    if (x509write_realloc_node(node, raw->len) != 0) 
     1119+        return 1; 
     1120+ 
     1121+    memcpy(node->p, raw->p, (size_t)raw->len); 
     1122+    if ((node->p += raw->len -1) != node->end) 
     1123+        return POLARSSL_ERR_X509_POINT_ERROR; 
     1124+ 
     1125+    return 0; 
     1126+} 
     1127+ 
     1128+/* 
     1129+ * Add the issuer 
     1130+ */ 
     1131+ 
     1132+int x509write_add_issuer(x509_raw *crt, unsigned char *issuer) 
     1133+{ 
     1134+    return x509write_parse_names(&crt->issuer, issuer); 
     1135+} 
     1136+ 
     1137+/* 
     1138+ * Add the subject 
     1139+ */ 
     1140+int x509write_add_subject(x509_raw *crt, unsigned char *subject) 
     1141+{ 
     1142+    return x509write_parse_names(&crt->subject, subject); 
     1143+} 
     1144+ 
     1145+/* 
     1146+ * Copy issuer line from another cert to issuer 
     1147+ */ 
     1148+int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt) 
     1149+{ 
     1150+    return x509write_copy_from_raw(&crt->issuer, &from_crt->issuer_raw); 
     1151+} 
     1152+ 
     1153+/* 
     1154+ * Copy subject line from another cert 
     1155+ */ 
     1156+int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt) 
     1157+{ 
     1158+    return x509write_copy_from_raw(&crt->subject, &from_crt->subject_raw); 
     1159+} 
     1160+ 
     1161+/* 
     1162+ * Copy subject line form antoher cert into issuer 
     1163+ */ 
     1164+int x509write_copy_issuer_form_subject(x509_raw *crt, 
     1165+        x509_cert *from_crt) 
     1166+{ 
     1167+    return x509write_copy_from_raw(&crt->issuer, &from_crt->subject_raw); 
     1168+} 
     1169+ 
     1170+/* 
     1171+ * Copy issuer line from another cert into subject 
     1172+ */ 
     1173+int x509write_copy_subject_from_issuer(x509_raw *crt, 
     1174+        x509_cert * from_crt) 
     1175+{ 
     1176+    return x509write_copy_from_raw(&crt->subject, &from_crt->issuer_raw); 
     1177+} 
     1178+ 
     1179+/* 
     1180+ *  Validity ::= SEQUENCE { 
     1181+ *       notBefore      Time, 
     1182+ *       notAfter       Time } 
     1183+ * 
     1184+ *  Time ::= CHOICE { 
     1185+ *       utcTime        UTCTime, 
     1186+ *       generalTime    GeneralizedTime } 
     1187+ */ 
     1188+/* TODO: No handle GeneralizedTime! */ 
     1189+int x509write_add_validity(x509_raw *chain, unsigned char *befor, 
     1190+        unsigned char *after) 
     1191+{ 
     1192+    int ret; 
     1193+ 
     1194+    x509_node *node = &chain->validity; 
     1195+ 
     1196+    /* notBefore */ 
     1197+    if ((ret = asn1_add_date_utc(befor, node)) != 0) 
     1198+        return ret; 
     1199+ 
     1200+    /* notAfter */ 
     1201+    if ((ret = asn1_add_date_utc(after, node)) != 0) 
     1202+        return ret; 
     1203+ 
     1204+    if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0) 
     1205+        return ret; 
     1206+ 
     1207+    return 0; 
     1208+} 
     1209+ 
     1210+/* 
     1211+ * make hash from tbs and sign that with private key 
     1212+ */ 
     1213+static int x509write_make_sign(x509_raw *chain, rsa_context *privkey) 
     1214+{ 
     1215+    int ret; 
     1216+    unsigned char hash[20], *sign; 
     1217+    size_t sign_len = (size_t) mpi_size(&privkey->N); 
     1218+ 
     1219+    /* make hash */ 
     1220+    sha1(chain->tbs.data, chain->tbs.len, hash); 
     1221+ 
     1222+    /* create sign */ 
     1223+    sign = (unsigned char *) malloc(sign_len); 
     1224+    if (sign == NULL) 
     1225+        return 1; 
     1226+ 
     1227+    if ((ret = rsa_pkcs1_sign(privkey, RSA_PRIVATE, SIG_RSA_SHA1, 20, hash, 
     1228+                    sign)) != 0) 
     1229+        return ret; 
     1230+ 
     1231+    if ((ret = asn1_add_obj(sign, sign_len, ASN1_BIT_STRING, 
     1232+                    &chain->sign)) != 0) 
     1233+        return ret; 
     1234+ 
     1235+    /* 
     1236+     *  AlgorithmIdentifier  ::=  SEQUENCE  { 
     1237+     *       algorithm               OBJECT IDENTIFIER, 
     1238+     *       parameters              ANY DEFINED BY algorithm OPTIONAL  } 
     1239+     */ 
     1240+    return asn1_add_oid(&chain->signalg, (unsigned char*)OID_PKCS1_RSA_SHA, 9, 
     1241+                  ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL, 
     1242+                  (unsigned char*)"", 0); 
     1243+} 
     1244+ 
     1245+/* 
     1246+ * Create a self signed certificate 
     1247+ */ 
     1248+int x509write_create_sign(x509_raw *chain, rsa_context *privkey) 
     1249+{ 
     1250+    int ret, serial; 
     1251+ 
     1252+    /* 
     1253+     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  } 
     1254+     */ 
     1255+    if ((ret = asn1_add_int(2, &chain->version)) != 0) 
     1256+        return ret; 
     1257+ 
     1258+    if ((ret = asn1_append_tag(&chain->version, ASN1_CONTEXT_SPECIFIC | 
     1259+                    ASN1_CONSTRUCTED)) != 0) 
     1260+        return ret; 
     1261+ 
     1262+ 
     1263+    /* 
     1264+     *  CertificateSerialNumber  ::=  INTEGER 
     1265+     */ 
     1266+    srand((unsigned int) time(NULL)); 
     1267+    serial = rand(); 
     1268+    if ((ret = asn1_add_int(serial, &chain->serial)) != 0) 
     1269+        return ret; 
     1270+ 
     1271+    /* 
     1272+     *  AlgorithmIdentifier  ::=  SEQUENCE  { 
     1273+     *       algorithm               OBJECT IDENTIFIER, 
     1274+     *       parameters              ANY DEFINED BY algorithm OPTIONAL  } 
     1275+     */ 
     1276+    if ((ret = asn1_add_oid(&chain->tbs_signalg, 
     1277+                               (unsigned char*)OID_PKCS1_RSA_SHA, 9, ASN1_CONSTRUCTED | 
     1278+                               ASN1_SEQUENCE, ASN1_NULL, (unsigned char*)"", 0)) != 0) 
     1279+        return ret; 
     1280+ 
     1281+   /* 
     1282+    *  Create the tbs 
     1283+    */ 
     1284+    if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | 
     1285+                    ASN1_SEQUENCE, 7, &chain->version, &chain->serial, 
     1286+                    &chain->tbs_signalg, &chain->issuer, &chain->validity, 
     1287+                    &chain->subject, &chain->subpubkey)) != 0) 
     1288+        return ret; 
     1289+ 
     1290+    /* make signing */ 
     1291+    if ((ret = x509write_make_sign(chain, privkey)) != 0) 
     1292+        return ret; 
     1293+ 
     1294+    /* finishing */ 
     1295+    if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | 
     1296+                    ASN1_SEQUENCE, 3, &chain->tbs, &chain->signalg, 
     1297+                    &chain->sign)) != 0) 
     1298+        return ret; 
     1299+ 
     1300+    return 0; 
     1301+} 
     1302+ 
     1303+int x509write_create_selfsign(x509_raw *chain, rsa_context *privkey) 
     1304+{ 
     1305+    /* 
     1306+     * On self signed certificate are subject and issuer the same 
     1307+     */ 
     1308+    x509write_free_node(&chain->issuer); 
     1309+    chain->issuer = chain->subject; 
     1310+    return x509write_create_sign(chain, privkey); 
     1311+} 
     1312+ 
     1313+/* 
     1314+ * CertificationRequestInfo ::= SEQUENCE                    { 
     1315+ *    version                       Version, 
     1316+ *    subject                       Name, 
     1317+ *    subjectPublicKeyInfo          SubjectPublicKeyInfo, 
     1318+ *    attributes                    [0] IMPLICIT Attributes } 
     1319+ * 
     1320+ * CertificationRequest ::=   SEQUENCE                      { 
     1321+ *    certificationRequestInfo  CertificationRequestInfo, 
     1322+ *    signatureAlgorithm        SignatureAlgorithmIdentifier, 
     1323+ *    signature                 Signature                   } 
     1324+ * 
     1325+ * It use chain.serail for attributes! 
     1326+ * 
     1327+ */ 
     1328+int x509write_create_csr(x509_raw *chain, rsa_context *privkey) 
     1329+{ 
     1330+    int ret; 
     1331+ 
     1332+    /* version ::= INTEGER */ 
     1333+    if ((ret = asn1_add_int(0, &chain->version)) != 0) 
     1334+        return ret; 
     1335+ 
     1336+    /* write attributes */ 
     1337+    if ((ret = asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC | 
     1338+                    ASN1_CONSTRUCTED, &chain->serial)) != 0) 
     1339+        return ret; 
     1340+ 
     1341+    /* create CertificationRequestInfo */ 
     1342+    if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED | 
     1343+                    ASN1_SEQUENCE, 4, &chain->version, &chain->subject, 
     1344+                    &chain->subpubkey, &chain->serial)) != 0) 
     1345+        return ret; 
     1346+ 
     1347+    /* make signing */ 
     1348+    if ((ret = x509write_make_sign(chain, privkey)) != 0) 
     1349+        return ret; 
     1350+ 
     1351+    /* finish */ 
     1352+    if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 
     1353+                    3, &chain->tbs, &chain->signalg, &chain->sign)) != 0) 
     1354+        return ret; 
     1355+ 
     1356+    return ret; 
     1357+} 
     1358+ 
     1359+/* 
     1360+ * Free memory 
     1361+ */ 
     1362+void x509write_free_raw(x509_raw *chain) 
     1363+{ 
     1364+    x509write_free_node(&chain->raw); 
     1365+    x509write_free_node(&chain->tbs); 
     1366+    x509write_free_node(&chain->version); 
     1367+    x509write_free_node(&chain->serial); 
     1368+    x509write_free_node(&chain->tbs_signalg); 
     1369+    x509write_free_node(&chain->issuer); 
     1370+    x509write_free_node(&chain->validity); 
     1371+    if (chain->subject.data != chain->issuer.data) 
     1372+        x509write_free_node(&chain->subject); 
     1373+    x509write_free_node(&chain->subpubkey); 
     1374+    x509write_free_node(&chain->signalg); 
     1375+    x509write_free_node(&chain->sign); 
     1376+} 
     1377+ 
     1378+void x509write_init_raw(x509_raw *chain) 
     1379+{ 
     1380+    memset((void *) chain, 0, sizeof(x509_raw)); 
     1381+} 
  • make/libs/external.in

     
    280280                externals these file(s): 
    281281                 /usr/lib/freetz/libpng12.so.0.42.0 
    282282 
     283config EXTERNAL_FREETZ_LIB_libpolarssl 
     284        depends on EXTERNAL_ENABLED && FREETZ_LIB_libpolarssl 
     285        bool "libpolarssl" 
     286        default n 
     287        help 
     288                externals these file(s): 
     289                 /usr/lib/freetz/libpolarssl.so.0.12.1 
     290 
    283291config EXTERNAL_FREETZ_LIB_libpopt 
    284292        depends on EXTERNAL_ENABLED && FREETZ_LIB_libpopt 
    285293        bool "libpopt" 
  • make/libs/polarssl.mk

     
     1$(call PKG_INIT_LIB, 0.12.1) 
     2$(PKG)_SOURCE:=$(pkg)-$($(PKG)_VERSION)-gpl.tgz 
     3$(PKG)_SOURCE_MD5:=08bc85a19bbe65493076b9968b421e80 
     4$(PKG)_SITE:=http://$(pkg).org/code/releases 
     5 
     6$(PKG)_LIBNAME:=lib$(pkg).so.$($(PKG)_VERSION) 
     7$(PKG)_BINARY:=$($(PKG)_DIR)/library/$($(PKG)_LIBNAME) 
     8$(PKG)_STAGING_BINARY:=$(TARGET_TOOLCHAIN_STAGING_DIR)/usr/lib/$($(PKG)_LIBNAME) 
     9$(PKG)_TARGET_BINARY:=$($(PKG)_TARGET_DIR)/$($(PKG)_LIBNAME) 
     10 
     11$(PKG_SOURCE_DOWNLOAD) 
     12$(PKG_UNPACKED) 
     13$(PKG_CONFIGURED_NOP) 
     14 
     15$($(PKG)_BINARY): $($(PKG)_DIR)/.configured 
     16        $(SUBMAKE) -C $(POLARSSL_DIR)/library \ 
     17                VERSION="$(POLARSSL_VERSION)" \ 
     18                CC="$(TARGET_CC)" \ 
     19                CFLAGS="$(TARGET_CFLAGS) $(FPIC) -I../include" \ 
     20                OFLAGS="" \ 
     21                AR="$(TARGET_CROSS)ar" \ 
     22                RANLIB="$(TARGET_CROSS)ranlib" \ 
     23                STRIP="$(TARGET_CROSS)strip" \ 
     24                shared 
     25 
     26$($(PKG)_STAGING_BINARY): $($(PKG)_BINARY) 
     27        mkdir -p $(TARGET_TOOLCHAIN_STAGING_DIR)/usr/include 
     28        cp -a $(POLARSSL_DIR)/include/polarssl $(TARGET_TOOLCHAIN_STAGING_DIR)/usr/include/ 
     29        $(INSTALL_LIBRARY) 
     30 
     31$($(PKG)_TARGET_BINARY): $($(PKG)_STAGING_BINARY) 
     32        $(INSTALL_LIBRARY_STRIP) 
     33 
     34$(pkg): $($(PKG)_STAGING_BINARY) 
     35 
     36$(pkg)-precompiled: $($(PKG)_TARGET_BINARY) 
     37 
     38$(pkg)-clean: 
     39        -$(SUBMAKE) -C $(POLARSSL_DIR)/library clean 
     40        $(RM) -r \ 
     41                $(TARGET_TOOLCHAIN_STAGING_DIR)/usr/lib/libpolarssl* \ 
     42                $(TARGET_TOOLCHAIN_STAGING_DIR)/usr/include/polarssl/ 
     43 
     44$(pkg)-uninstall: 
     45        $(RM) $(POLARSSL_TARGET_DIR)/libpolarssl.so* 
     46 
     47$(PKG_FINISH) 
  • make/libs/Config.in

     
    138138 
    139139                In Freetz, xrelayd depends on XySSL. 
    140140 
     141config FREETZ_LIB_libpolarssl 
     142        bool "PolarSSL (libpolarssl.so)" 
     143        default n 
     144        help 
     145                The aim of the PolarSSL project is to provide a quality, open-source 
     146                cryptographic library written in C and targeted at embedded systems. 
     147                PolarSSL is licensed accoring to the dual licensing model. This means 
     148                that PolarSSL is available under the open source GPL version 2 license 
     149                as well as a commercial license for closed source projects. More 
     150                information about licensing is available on the Licensing page: 
     151                http://polarssl.org/?page=licensing 
     152 
     153                For more information about this project, please contact: 
     154                http://polarssl.org/?page=contact 
     155                Web site: http://polarssl.org/ 
     156 
     157                In Freetz, umurmur depends on PolarSSL. 
     158 
    141159config FREETZ_LIB_libcrypto 
    142160        bool "OpenSSL cryptographic library (libcrypto.so)" 
    143161        select FREETZ_LIB_libssl if FREETZ_HAS_LIBSSL 
  • tools/external

     
    7373[ "$EXTERNAL_FREETZ_LIB_libpcre" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libpcre.so.0.0.1" 
    7474[ "$EXTERNAL_FREETZ_LIB_libpcreposix" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libpcreposix.so.0.0.0" 
    7575[ "$EXTERNAL_FREETZ_LIB_libpng12" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libpng12.so.0.42.0" 
     76[ "$EXTERNAL_FREETZ_LIB_libpolarssl" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libpolarssl.so.0.12.1" 
    7677[ "$EXTERNAL_FREETZ_LIB_libpopt" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libpopt.so.0.0.0" 
    7778[ "$EXTERNAL_FREETZ_LIB_libreadline" == "y" ] && EXTERNAL_FILES+=" /usr/lib/freetz/libreadline.so.6.1" 
    7879[ "$EXTERNAL_FREETZ_LIB_libresolv" == "y" ] && EXTERNAL_FILES+=" /lib/libresolv-${FREETZ_TARGET_UCLIBC_VERSION}.so"