Import OpenSSL 0.9.8e.
authorPeter Avalos <pavalos@dragonflybsd.org>
Wed, 28 Mar 2007 19:01:30 +0000 (19:01 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Wed, 28 Mar 2007 19:01:30 +0000 (19:01 +0000)
166 files changed:
crypto/openssl-0.9/CHANGES
crypto/openssl-0.9/FAQ
crypto/openssl-0.9/LICENSE
crypto/openssl-0.9/NEWS
crypto/openssl-0.9/README
crypto/openssl-0.9/apps/CA.pl
crypto/openssl-0.9/apps/ca.c
crypto/openssl-0.9/apps/dgst.c
crypto/openssl-0.9/apps/ec.c
crypto/openssl-0.9/apps/enc.c
crypto/openssl-0.9/apps/ocsp.c
crypto/openssl-0.9/apps/pkcs12.c
crypto/openssl-0.9/apps/s_client.c
crypto/openssl-0.9/apps/s_server.c
crypto/openssl-0.9/crypto/aes/aes_misc.c
crypto/openssl-0.9/crypto/asn1/a_strex.c
crypto/openssl-0.9/crypto/asn1/asn1_err.c
crypto/openssl-0.9/crypto/asn1/asn1_lib.c
crypto/openssl-0.9/crypto/asn1/asn1t.h
crypto/openssl-0.9/crypto/asn1/t_x509.c
crypto/openssl-0.9/crypto/asn1/tasn_dec.c
crypto/openssl-0.9/crypto/asn1/x_x509.c
crypto/openssl-0.9/crypto/bf/bf_ecb.c
crypto/openssl-0.9/crypto/bio/bio.h
crypto/openssl-0.9/crypto/bio/bio_err.c
crypto/openssl-0.9/crypto/bio/bio_lib.c
crypto/openssl-0.9/crypto/bn/bn_err.c
crypto/openssl-0.9/crypto/bn/bn_lib.c
crypto/openssl-0.9/crypto/bn/bn_print.c
crypto/openssl-0.9/crypto/buffer/buf_err.c
crypto/openssl-0.9/crypto/camellia/camellia.c
crypto/openssl-0.9/crypto/camellia/cmll_cbc.c
crypto/openssl-0.9/crypto/camellia/cmll_locl.h
crypto/openssl-0.9/crypto/camellia/cmll_misc.c
crypto/openssl-0.9/crypto/cast/c_ecb.c
crypto/openssl-0.9/crypto/comp/c_zlib.c
crypto/openssl-0.9/crypto/comp/comp_err.c
crypto/openssl-0.9/crypto/conf/conf_def.c
crypto/openssl-0.9/crypto/conf/conf_err.c
crypto/openssl-0.9/crypto/conf/conf_lib.c
crypto/openssl-0.9/crypto/cpt_err.c
crypto/openssl-0.9/crypto/cryptlib.c
crypto/openssl-0.9/crypto/des/des_ver.h
crypto/openssl-0.9/crypto/des/ecb_enc.c
crypto/openssl-0.9/crypto/dh/dh_err.c
crypto/openssl-0.9/crypto/dh/dh_key.c
crypto/openssl-0.9/crypto/dh/dh_lib.c
crypto/openssl-0.9/crypto/dsa/dsa_err.c
crypto/openssl-0.9/crypto/dsa/dsa_lib.c
crypto/openssl-0.9/crypto/dso/dso_err.c
crypto/openssl-0.9/crypto/ec/ec_asn1.c
crypto/openssl-0.9/crypto/ec/ec_err.c
crypto/openssl-0.9/crypto/ecdh/ech_err.c
crypto/openssl-0.9/crypto/ecdh/ech_lib.c
crypto/openssl-0.9/crypto/ecdsa/ecdsa.h
crypto/openssl-0.9/crypto/ecdsa/ecs_err.c
crypto/openssl-0.9/crypto/ecdsa/ecs_lib.c
crypto/openssl-0.9/crypto/ecdsa/ecs_ossl.c
crypto/openssl-0.9/crypto/engine/eng_all.c
crypto/openssl-0.9/crypto/engine/eng_err.c
crypto/openssl-0.9/crypto/engine/eng_padlock.c
crypto/openssl-0.9/crypto/engine/tb_ecdh.c
crypto/openssl-0.9/crypto/engine/tb_ecdsa.c
crypto/openssl-0.9/crypto/err/err_all.c
crypto/openssl-0.9/crypto/evp/bio_md.c
crypto/openssl-0.9/crypto/evp/evp.h
crypto/openssl-0.9/crypto/evp/evp_enc.c
crypto/openssl-0.9/crypto/evp/evp_err.c
crypto/openssl-0.9/crypto/evp/evp_lib.c
crypto/openssl-0.9/crypto/evp/evp_locl.h
crypto/openssl-0.9/crypto/idea/i_ecb.c
crypto/openssl-0.9/crypto/idea/idea_lcl.h
crypto/openssl-0.9/crypto/lhash/lhash.c
crypto/openssl-0.9/crypto/md2/md2.h
crypto/openssl-0.9/crypto/md2/md2_dgst.c
crypto/openssl-0.9/crypto/md4/md4.h
crypto/openssl-0.9/crypto/md4/md4_dgst.c
crypto/openssl-0.9/crypto/md5/md5.h
crypto/openssl-0.9/crypto/md5/md5_dgst.c
crypto/openssl-0.9/crypto/objects/obj_dat.h
crypto/openssl-0.9/crypto/objects/obj_err.c
crypto/openssl-0.9/crypto/objects/obj_mac.h
crypto/openssl-0.9/crypto/ocsp/ocsp_asn.c
crypto/openssl-0.9/crypto/ocsp/ocsp_err.c
crypto/openssl-0.9/crypto/ocsp/ocsp_vfy.c
crypto/openssl-0.9/crypto/opensslv.h
crypto/openssl-0.9/crypto/pem/pem.h
crypto/openssl-0.9/crypto/pem/pem_err.c
crypto/openssl-0.9/crypto/pem/pem_lib.c
crypto/openssl-0.9/crypto/pem/pem_pkey.c
crypto/openssl-0.9/crypto/pkcs12/pk12err.c
crypto/openssl-0.9/crypto/pkcs7/pk7_doit.c
crypto/openssl-0.9/crypto/pkcs7/pk7_lib.c
crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c
crypto/openssl-0.9/crypto/pkcs7/pkcs7err.c
crypto/openssl-0.9/crypto/rand/md_rand.c
crypto/openssl-0.9/crypto/rand/rand_err.c
crypto/openssl-0.9/crypto/rc2/rc2_ecb.c
crypto/openssl-0.9/crypto/rc4/rc4_skey.c
crypto/openssl-0.9/crypto/ripemd/ripemd.h
crypto/openssl-0.9/crypto/ripemd/rmd_dgst.c
crypto/openssl-0.9/crypto/rsa/rsa_err.c
crypto/openssl-0.9/crypto/rsa/rsa_lib.c
crypto/openssl-0.9/crypto/sha/sha.h
crypto/openssl-0.9/crypto/sha/sha1dgst.c
crypto/openssl-0.9/crypto/sha/sha256.c
crypto/openssl-0.9/crypto/sha/sha512.c
crypto/openssl-0.9/crypto/sha/sha_dgst.c
crypto/openssl-0.9/crypto/stack/safestack.h
crypto/openssl-0.9/crypto/stack/stack.c
crypto/openssl-0.9/crypto/store/str_err.c
crypto/openssl-0.9/crypto/txt_db/txt_db.c
crypto/openssl-0.9/crypto/ui/ui_err.c
crypto/openssl-0.9/crypto/x509/by_dir.c
crypto/openssl-0.9/crypto/x509/x509.h
crypto/openssl-0.9/crypto/x509/x509_err.c
crypto/openssl-0.9/crypto/x509/x509_req.c
crypto/openssl-0.9/crypto/x509/x509_txt.c
crypto/openssl-0.9/crypto/x509/x509_vfy.c
crypto/openssl-0.9/crypto/x509/x509_vfy.h
crypto/openssl-0.9/crypto/x509v3/ext_dat.h
crypto/openssl-0.9/crypto/x509v3/pcy_tree.c
crypto/openssl-0.9/crypto/x509v3/v3_addr.c [new file with mode: 0644]
crypto/openssl-0.9/crypto/x509v3/v3_akey.c
crypto/openssl-0.9/crypto/x509v3/v3_alt.c
crypto/openssl-0.9/crypto/x509v3/v3_asid.c [new file with mode: 0644]
crypto/openssl-0.9/crypto/x509v3/v3_bcons.c
crypto/openssl-0.9/crypto/x509v3/v3_bitst.c
crypto/openssl-0.9/crypto/x509v3/v3_cpols.c
crypto/openssl-0.9/crypto/x509v3/v3_crld.c
crypto/openssl-0.9/crypto/x509v3/v3_enum.c
crypto/openssl-0.9/crypto/x509v3/v3_extku.c
crypto/openssl-0.9/crypto/x509v3/v3_ia5.c
crypto/openssl-0.9/crypto/x509v3/v3_info.c
crypto/openssl-0.9/crypto/x509v3/v3_int.c
crypto/openssl-0.9/crypto/x509v3/v3_ncons.c
crypto/openssl-0.9/crypto/x509v3/v3_ocsp.c
crypto/openssl-0.9/crypto/x509v3/v3_pci.c
crypto/openssl-0.9/crypto/x509v3/v3_pcons.c
crypto/openssl-0.9/crypto/x509v3/v3_pku.c
crypto/openssl-0.9/crypto/x509v3/v3_pmaps.c
crypto/openssl-0.9/crypto/x509v3/v3_purp.c
crypto/openssl-0.9/crypto/x509v3/v3_skey.c
crypto/openssl-0.9/crypto/x509v3/v3_sxnet.c
crypto/openssl-0.9/crypto/x509v3/v3_utl.c
crypto/openssl-0.9/crypto/x509v3/v3err.c
crypto/openssl-0.9/crypto/x509v3/x509v3.h
crypto/openssl-0.9/ssl/d1_lib.c
crypto/openssl-0.9/ssl/d1_pkt.c
crypto/openssl-0.9/ssl/kssl.c
crypto/openssl-0.9/ssl/s23_clnt.c
crypto/openssl-0.9/ssl/s23_srvr.c
crypto/openssl-0.9/ssl/s2_enc.c
crypto/openssl-0.9/ssl/s2_lib.c
crypto/openssl-0.9/ssl/s3_clnt.c
crypto/openssl-0.9/ssl/s3_enc.c
crypto/openssl-0.9/ssl/s3_lib.c
crypto/openssl-0.9/ssl/s3_pkt.c
crypto/openssl-0.9/ssl/s3_srvr.c
crypto/openssl-0.9/ssl/ssl.h
crypto/openssl-0.9/ssl/ssl_ciph.c
crypto/openssl-0.9/ssl/ssl_err.c
crypto/openssl-0.9/ssl/ssl_lib.c
crypto/openssl-0.9/ssl/ssl_sess.c
crypto/openssl-0.9/ssl/t1_enc.c
crypto/openssl-0.9/ssl/t1_lib.c

index b25fde5..c5a639f 100644 (file)
@@ -2,6 +2,47 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Since AES128 and AES256 (and similarly Camellia128 and
+     Camellia256) share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't
+     (or if Camellia128 is available and Camellia256 isn't).
+     [Victor Duchovni]
+
+  *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
+     (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
+     When a point or a seed is encoded in a BIT STRING, we need to
+     prevent the removal of trailing zero bits to get the proper DER
+     encoding.  (By default, crypto/asn1/a_bitstr.c assumes the case
+     of a NamedBitList, for which trailing 0 bits need to be removed.)
+     [Bodo Moeller]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Add RFC 3779 support.
+     [Rob Austein for ARIN, Ben Laurie]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     Improve header file function name parsing.
+     [Steve Henson]
+
+  *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
+     or CAPABILITY handshake as required by RFCs.
+     [Goetz Babin-Ebell]
+
  Changes between 0.9.8c and 0.9.8d  [28 Sep 2006]
 
   *) Introduce limits to prevent malicious keys being able to
      draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
      appear there.
 
-     Also deactive the remaining ciphersuites from
+     Also deactivate the remaining ciphersuites from
      draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
      unofficial, and the ID has long expired.
      [Bodo Moeller]
      differing sizes.
      [Richard Levitte]
 
- Changes between 0.9.7k and 0.9.7l  [xx XXX xxxx]
+ Changes between 0.9.7l and 0.9.7m  [xx XXX xxxx]
+
+  *) Cleanse PEM buffers before freeing them since they may contain 
+     sensitive data.
+     [Benjamin Bennett <ben@psc.edu>]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Since AES128 and AES256 share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't.
+     [Victor Duchovni]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     [Steve Henson]
+
+ Changes between 0.9.7k and 0.9.7l  [28 Sep 2006]
+
+  *) Introduce limits to prevent malicious keys being able to
+     cause a denial of service.  (CVE-2006-2940)
+     [Steve Henson, Bodo Moeller]
+
+  *) Fix ASN.1 parsing of certain invalid structures that can result
+     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
+
+  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
+     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Fix SSL client code which could crash if connecting to a
+     malicious SSLv2 server.  (CVE-2006-4343)
+     [Tavis Ormandy and Will Drewry, Google Security Team]
 
   *) Change ciphersuite string processing so that an explicit
      ciphersuite selects this one ciphersuite (so that "AES256-SHA"
index bee5094..74bf952 100644 (file)
@@ -74,7 +74,7 @@ OpenSSL  -  Frequently Asked Questions
 * Which is the current version of OpenSSL?
 
 The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 0.9.8d was released on September 28th, 2006.
+OpenSSL 0.9.8e was released on February 23rd, 2007.
 
 In addition to the current stable release, you can also access daily
 snapshots of the OpenSSL development version at <URL:
index c21f132..ff99d97 100644 (file)
@@ -12,7 +12,7 @@
   ---------------
 
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index ad8033a..c808a76 100644 (file)
@@ -5,7 +5,12 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
-  Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.8d:
+  Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
+
+      o Various ciphersuite selection fixes.
+      o RFC3779 support.
+
+  Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d:
 
       o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
       o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
       o Added initial support for Win64.
       o Added alternate pkg-config files.
 
+  Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
+
+      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
+      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+
   Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k:
 
       o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
index e627231..907e235 100644 (file)
@@ -1,7 +1,7 @@
 
- OpenSSL 0.9.8d 28 Sep 2006
+ OpenSSL 0.9.8e 23 Feb 2007
 
- Copyright (c) 1998-2006 The OpenSSL Project
+ Copyright (c) 1998-2007 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
  All rights reserved.
 
index c783a6e..a3965ec 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/local/bin/perl
+#!/usr/bin/perl
 #
 # CA - wrapper around ca to make it easier to use ... basically ca requires
 #      some setup stuff to be done before you can use it and this makes
index 210b5e1..e9d79de 100644 (file)
@@ -1520,6 +1520,7 @@ err:
        if (x509) X509_free(x509);
        X509_CRL_free(crl);
        NCONF_free(conf);
+       NCONF_free(extconf);
        OBJ_cleanup();
        apps_shutdown();
        OPENSSL_EXIT(ret);
index c13535f..09d0934 100644 (file)
@@ -66,6 +66,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
+#include <openssl/hmac.h>
 
 #undef BUFSIZE
 #define BUFSIZE        1024*8
@@ -75,7 +76,7 @@
 
 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
          EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
-         const char *file);
+         const char *file,BIO *bmd,const char *hmac_key);
 
 int MAIN(int, char **);
 
@@ -104,6 +105,7 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_ENGINE
        char *engine=NULL;
 #endif
+       char *hmac_key=NULL;
 
        apps_startup();
 
@@ -188,6 +190,12 @@ int MAIN(int argc, char **argv)
                        out_bin = 1;
                else if (strcmp(*argv,"-d") == 0)
                        debug=1;
+               else if (!strcmp(*argv,"-hmac"))
+                       {
+                       if (--argc < 1)
+                               break;
+                       hmac_key=*++argv;
+                       }
                else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
                        md=m;
                else
@@ -261,7 +269,7 @@ int MAIN(int argc, char **argv)
                {
                BIO_set_callback(in,BIO_debug_callback);
                /* needed for windows 3.1 */
-               BIO_set_callback_arg(in,bio_err);
+               BIO_set_callback_arg(in,(char *)bio_err);
                }
 
        if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
@@ -358,7 +366,7 @@ int MAIN(int argc, char **argv)
                {
                BIO_set_fp(in,stdin,BIO_NOCLOSE);
                err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
-                         siglen,"","(stdin)");
+                         siglen,"","(stdin)",bmd,hmac_key);
                }
        else
                {
@@ -376,14 +384,15 @@ int MAIN(int argc, char **argv)
                                }
                        if(!out_bin)
                                {
-                               size_t len = strlen(name)+strlen(argv[i])+5;
+                               size_t len = strlen(name)+strlen(argv[i])+(hmac_key ? 5 : 0)+5;
                                tmp=tofree=OPENSSL_malloc(len);
-                               BIO_snprintf(tmp,len,"%s(%s)= ",name,argv[i]);
+                               BIO_snprintf(tmp,len,"%s%s(%s)= ",
+                                                        hmac_key ? "HMAC-" : "",name,argv[i]);
                                }
                        else
                                tmp="";
                        r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
-                               siglen,tmp,argv[i]);
+                               siglen,tmp,argv[i],bmd,hmac_key);
                        if(r)
                            err=r;
                        if(tofree)
@@ -410,11 +419,23 @@ end:
 
 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
          EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
-         const char *file)
+         const char *file,BIO *bmd,const char *hmac_key)
        {
-       int len;
+       unsigned int len;
        int i;
+       EVP_MD_CTX *md_ctx;
+       HMAC_CTX hmac_ctx;
+
+       if (hmac_key)
+               {
+               EVP_MD *md;
 
+               BIO_get_md(bmd,&md);
+               HMAC_CTX_init(&hmac_ctx);
+               HMAC_Init_ex(&hmac_ctx,hmac_key,strlen(hmac_key),md, NULL);
+               BIO_get_md_ctx(bmd,&md_ctx);
+               BIO_set_md_ctx(bmd,&hmac_ctx.md_ctx);
+               }
        for (;;)
                {
                i=BIO_read(bp,(char *)buf,BUFSIZE);
@@ -457,6 +478,11 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
                        return 1;
                        }
                }
+       else if(hmac_key)
+               {
+               HMAC_Final(&hmac_ctx,buf,&len);
+               HMAC_CTX_cleanup(&hmac_ctx);
+               }
        else
                len=BIO_gets(bp,(char *)buf,BUFSIZE);
 
@@ -464,7 +490,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
        else 
                {
                BIO_write(out,title,strlen(title));
-               for (i=0; i<len; i++)
+               for (i=0; i<(int)len; i++)
                        {
                        if (sep && (i != 0))
                                BIO_printf(out, ":");
@@ -472,6 +498,10 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
                        }
                BIO_printf(out, "\n");
                }
+       if (hmac_key)
+               {
+               BIO_set_md_ctx(bmd,md_ctx);
+               }
        return 0;
        }
 
index 9ddaddf..c63437f 100644 (file)
@@ -347,7 +347,10 @@ bad:
                        }
 
        if (noout) 
+               {
+               ret = 0;
                goto end;
+               }
 
        BIO_printf(bio_err, "writing EC key\n");
        if (outformat == FORMAT_ASN1) 
index 3e3e8eb..a41ea80 100644 (file)
@@ -365,8 +365,8 @@ bad:
                {
                BIO_set_callback(in,BIO_debug_callback);
                BIO_set_callback(out,BIO_debug_callback);
-               BIO_set_callback_arg(in,bio_err);
-               BIO_set_callback_arg(out,bio_err);
+               BIO_set_callback_arg(in,(char *)bio_err);
+               BIO_set_callback_arg(out,(char *)bio_err);
                }
 
        if (inf == NULL)
@@ -453,7 +453,7 @@ bad:
                if (debug)
                        {
                        BIO_set_callback(b64,BIO_debug_callback);
-                       BIO_set_callback_arg(b64,bio_err);
+                       BIO_set_callback_arg(b64,(char *)bio_err);
                        }
                if (olb64)
                        BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
@@ -571,7 +571,7 @@ bad:
                if (debug)
                        {
                        BIO_set_callback(benc,BIO_debug_callback);
-                       BIO_set_callback_arg(benc,bio_err);
+                       BIO_set_callback_arg(benc,(char *)bio_err);
                        }
 
                if (printkey)
index 52af592..3ee6dfb 100644 (file)
@@ -139,6 +139,7 @@ int MAIN(int argc, char **argv)
        if (!load_config(bio_err, NULL))
                goto end;
        SSL_load_error_strings();
+       OpenSSL_add_ssl_algorithms();
        args = argv + 1;
        reqnames = sk_new_null();
        ids = sk_OCSP_CERTID_new_null();
@@ -726,6 +727,11 @@ int MAIN(int argc, char **argv)
                        BIO_printf(bio_err, "SSL is disabled\n");
                        goto end;
 #endif
+                       if (ctx == NULL)
+                               {
+                               BIO_printf(bio_err, "Error creating SSL context.\n");
+                               goto end;
+                               }
                        SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
                        sbio = BIO_new_ssl(ctx, 1);
                        cbio = BIO_push(sbio, cbio);
index 688a0ce..d5873e9 100644 (file)
@@ -536,8 +536,11 @@ int MAIN(int argc, char **argv)
                    X509_free(sk_X509_value(chain2, 0));
                    sk_X509_free(chain2);
                } else {
-                       BIO_printf (bio_err, "Error %s getting chain.\n",
+                       if (vret >= 0)
+                               BIO_printf (bio_err, "Error %s getting chain.\n",
                                        X509_verify_cert_error_string(vret));
+                       else
+                               ERR_print_errors(bio_err);
                        goto export_end;
                }                       
        }
@@ -811,7 +814,7 @@ int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
 {
        X509_STORE_CTX store_ctx;
        STACK_OF(X509) *chn;
-       int i;
+       int i = 0;
 
        /* FIXME: Should really check the return status of X509_STORE_CTX_init
         * for an error, but how that fits into the return value of this
@@ -819,13 +822,17 @@ int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
        X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
        if (X509_verify_cert(&store_ctx) <= 0) {
                i = X509_STORE_CTX_get_error (&store_ctx);
+               if (i == 0)
+                       /* avoid returning 0 if X509_verify_cert() did not
+                        * set an appropriate error value in the context */
+                       i = -1;
+               chn = NULL;
                goto err;
-       }
-       chn =  X509_STORE_CTX_get1_chain(&store_ctx);
-       i = 0;
-       *chain = chn;
+       } else
+               chn = X509_STORE_CTX_get1_chain(&store_ctx);
 err:
        X509_STORE_CTX_cleanup(&store_ctx);
+       *chain = chn;
        
        return i;
 }      
index 4a1857f..3f302c5 100644 (file)
@@ -226,7 +226,7 @@ static void sc_usage(void)
        BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
        BIO_printf(bio_err,"                 for those protocols that support it, where\n");
        BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
-       BIO_printf(bio_err,"                 only \"smtp\" and \"pop3\" are supported.\n");
+       BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", and \"ftp\" are supported.\n");
 #ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
 #endif
@@ -234,6 +234,15 @@ static void sc_usage(void)
 
        }
 
+enum
+{
+       PROTO_OFF       = 0,
+       PROTO_SMTP,
+       PROTO_POP3,
+       PROTO_IMAP,
+       PROTO_FTP
+};
+
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
@@ -260,7 +269,7 @@ int MAIN(int argc, char **argv)
        int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
        SSL_CTX *ctx=NULL;
        int ret=1,in_init=1,i,nbio_test=0;
-       int starttls_proto = 0;
+       int starttls_proto = PROTO_OFF;
        int prexit = 0, vflags = 0;
        SSL_METHOD *meth=NULL;
 #ifdef sock_type
@@ -269,6 +278,7 @@ int MAIN(int argc, char **argv)
        int sock_type=SOCK_STREAM;
        BIO *sbio;
        char *inrand=NULL;
+       int mbuf_len=0;
 #ifndef OPENSSL_NO_ENGINE
        char *engine_id=NULL;
        ENGINE *e=NULL;
@@ -466,9 +476,13 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        ++argv;
                        if (strcmp(*argv,"smtp") == 0)
-                               starttls_proto = 1;
+                               starttls_proto = PROTO_SMTP;
                        else if (strcmp(*argv,"pop3") == 0)
-                               starttls_proto = 2;
+                               starttls_proto = PROTO_POP3;
+                       else if (strcmp(*argv,"imap") == 0)
+                               starttls_proto = PROTO_IMAP;
+                       else if (strcmp(*argv,"ftp") == 0)
+                               starttls_proto = PROTO_FTP;
                        else
                                goto bad;
                        }
@@ -693,7 +707,7 @@ re_start:
                {
                con->debug=1;
                BIO_set_callback(sbio,bio_dump_callback);
-               BIO_set_callback_arg(sbio,bio_c_out);
+               BIO_set_callback_arg(sbio,(char *)bio_c_out);
                }
        if (c_msg)
                {
@@ -719,18 +733,93 @@ re_start:
        sbuf_off=0;
 
        /* This is an ugly hack that does a lot of assumptions */
-       if (starttls_proto == 1)
+       /* We do have to handle multi-line responses which may come
+          in a single packet or not. We therefore have to use
+          BIO_gets() which does need a buffering BIO. So during
+          the initial chitchat we do push a buffering BIO into the
+          chain that is removed again later on to not disturb the
+          rest of the s_client operation. */
+       if (starttls_proto == PROTO_SMTP)
                {
-               BIO_read(sbio,mbuf,BUFSIZZ);
+               int foundit=0;
+               BIO *fbio = BIO_new(BIO_f_buffer());
+               BIO_push(fbio, sbio);
+               /* wait for multi-line response to end from SMTP */
+               do
+                       {
+                       mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+                       }
+               while (mbuf_len>3 && mbuf[3]=='-');
+               /* STARTTLS command requires EHLO... */
+               BIO_printf(fbio,"EHLO openssl.client.net\r\n");
+               BIO_flush(fbio);
+               /* wait for multi-line response to end EHLO SMTP response */
+               do
+                       {
+                       mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+                       if (strstr(mbuf,"STARTTLS"))
+                               foundit=1;
+                       }
+               while (mbuf_len>3 && mbuf[3]=='-');
+               BIO_flush(fbio);
+               BIO_pop(fbio);
+               BIO_free(fbio);
+               if (!foundit)
+                       BIO_printf(bio_err,
+                                  "didn't found starttls in server response,"
+                                  " try anyway...\n");
                BIO_printf(sbio,"STARTTLS\r\n");
                BIO_read(sbio,sbuf,BUFSIZZ);
                }
-       if (starttls_proto == 2)
+       else if (starttls_proto == PROTO_POP3)
                {
                BIO_read(sbio,mbuf,BUFSIZZ);
                BIO_printf(sbio,"STLS\r\n");
                BIO_read(sbio,sbuf,BUFSIZZ);
                }
+       else if (starttls_proto == PROTO_IMAP)
+               {
+               int foundit=0;
+               BIO *fbio = BIO_new(BIO_f_buffer());
+               BIO_push(fbio, sbio);
+               BIO_gets(fbio,mbuf,BUFSIZZ);
+               /* STARTTLS command requires CAPABILITY... */
+               BIO_printf(fbio,". CAPABILITY\r\n");
+               BIO_flush(fbio);
+               /* wait for multi-line CAPABILITY response */
+               do
+                       {
+                       mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+                       if (strstr(mbuf,"STARTTLS"))
+                               foundit=1;
+                       }
+               while (mbuf_len>3 && mbuf[0]!='.');
+               BIO_flush(fbio);
+               BIO_pop(fbio);
+               BIO_free(fbio);
+               if (!foundit)
+                       BIO_printf(bio_err,
+                                  "didn't found STARTTLS in server response,"
+                                  " try anyway...\n");
+               BIO_printf(sbio,". STARTTLS\r\n");
+               BIO_read(sbio,sbuf,BUFSIZZ);
+               }
+       else if (starttls_proto == PROTO_FTP)
+               {
+               BIO *fbio = BIO_new(BIO_f_buffer());
+               BIO_push(fbio, sbio);
+               /* wait for multi-line response to end from FTP */
+               do
+                       {
+                       mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
+                       }
+               while (mbuf_len>3 && mbuf[3]=='-');
+               BIO_flush(fbio);
+               BIO_pop(fbio);
+               BIO_free(fbio);
+               BIO_printf(sbio,"AUTH TLS\r\n");
+               BIO_read(sbio,sbuf,BUFSIZZ);
+               }
 
        for (;;)
                {
@@ -755,7 +844,7 @@ re_start:
                                        {
                                        BIO_printf(bio_err,"%s",mbuf);
                                        /* We don't need to know any more */
-                                       starttls_proto = 0;
+                                       starttls_proto = PROTO_OFF;
                                        }
 
                                if (reconnect)
index 0d6727c..6c433e6 100644 (file)
@@ -1234,7 +1234,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                {
                con->debug=1;
                BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
-               BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
+               BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
                }
        if (s_msg)
                {
@@ -1638,7 +1638,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
                {
                con->debug=1;
                BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
-               BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
+               BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
                }
        if (s_msg)
                {
index 090def2..4fead1b 100644 (file)
@@ -53,7 +53,7 @@
 #include <openssl/aes.h>
 #include "aes_locl.h"
 
-const char *AES_version="AES" OPENSSL_VERSION_PTEXT;
+const char AES_version[]="AES" OPENSSL_VERSION_PTEXT;
 
 const char *AES_options(void) {
 #ifdef FULL_UNROLL
index fc743c2..c2dbb6f 100644 (file)
@@ -170,7 +170,7 @@ static int do_buf(unsigned char *buf, int buflen,
        q = buf + buflen;
        outlen = 0;
        while(p != q) {
-               if(p == buf) orflags = CHARTYPE_FIRST_ESC_2253;
+               if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
                else orflags = 0;
                switch(type & BUF_TYPE_WIDTH_MASK) {
                        case 4:
@@ -197,7 +197,7 @@ static int do_buf(unsigned char *buf, int buflen,
                        default:
                        return -1;      /* invalid width */
                }
-               if (p == q) orflags = CHARTYPE_LAST_ESC_2253;
+               if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
                if(type & BUF_TYPE_CONVUTF8) {
                        unsigned char utfbuf[6];
                        int utflen;
index c672d2e..f6b5c3f 100644 (file)
@@ -123,7 +123,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I),        "ASN1_TEMPLATE_EX_D2I"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW),   "ASN1_TEMPLATE_NEW"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I),     "ASN1_TEMPLATE_NOEXP_D2I"},
-{ERR_FUNC(ASN1_F_ASN1_TIME_SET),       "ASN1_TIME_SET"},
+{ERR_FUNC(ASN1_F_ASN1_TIME_SET),       "ASN1_TIME_set"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),       "ASN1_TYPE_get_int_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING),   "ASN1_TYPE_get_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING),  "ASN1_unpack_string"},
@@ -168,10 +168,10 @@ static ERR_STRING_DATA ASN1_str_functs[]=
 {ERR_FUNC(ASN1_F_OID_MODULE_INIT),     "OID_MODULE_INIT"},
 {ERR_FUNC(ASN1_F_PARSE_TAGGING),       "PARSE_TAGGING"},
 {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET),      "PKCS5_pbe2_set"},
-{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),       "PKCS5_PBE_SET"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE_SET),       "PKCS5_pbe_set"},
 {ERR_FUNC(ASN1_F_X509_CINF_NEW),       "X509_CINF_NEW"},
-{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),       "X509_CRL_ADD0_REVOKED"},
-{ERR_FUNC(ASN1_F_X509_INFO_NEW),       "X509_INFO_NEW"},
+{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED),       "X509_CRL_add0_revoked"},
+{ERR_FUNC(ASN1_F_X509_INFO_NEW),       "X509_INFO_new"},
 {ERR_FUNC(ASN1_F_X509_NAME_ENCODE),    "X509_NAME_ENCODE"},
 {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I),    "X509_NAME_EX_D2I"},
 {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW),    "X509_NAME_EX_NEW"},
@@ -287,15 +287,12 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 
 void ERR_load_ASN1_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,ASN1_str_functs);
                ERR_load_strings(0,ASN1_str_reasons);
-#endif
-
                }
+#endif
        }
index bb94257..d5ae5b2 100644 (file)
@@ -64,7 +64,7 @@
 
 static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
 static void asn1_put_length(unsigned char **pp, int length);
-const char *ASN1_version="ASN.1" OPENSSL_VERSION_PTEXT;
+const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
 
 static int _asn1_check_infinite_end(const unsigned char **p, long len)
        {
index cc0cd1c..adbc2a6 100644 (file)
@@ -99,7 +99,7 @@ extern "C" {
 #define ASN1_ITEM_start(itname) \
        const ASN1_ITEM * itname##_it(void) \
        { \
-               static const ASN1_ITEM local_it = { \
+               static const ASN1_ITEM local_it = { 
 
 #define ASN1_ITEM_end(itname) \
                }; \
index 61f48d1..fe2ea40 100644 (file)
@@ -445,9 +445,9 @@ err:
 int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
        {
        char *s,*c,*b;
-       int ret=0,l,ll,i,first=1;
+       int ret=0,l,i;
 
-       ll=80-2-obase;
+       l=80-2-obase;
 
        b=s=X509_NAME_oneline(name,NULL,0);
        if (!*s)
@@ -457,7 +457,6 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
                }
        s++; /* skip the first slash */
 
-       l=ll;
        c=s;
        for (;;)
                {
@@ -479,16 +478,6 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
                        (*s == '\0'))
 #endif
                        {
-                       if ((l <= 0) && !first)
-                               {
-                               first=0;
-                               if (BIO_write(bp,"\n",1) != 1) goto err;
-                               for (i=0; i<obase; i++)
-                                       {
-                                       if (BIO_write(bp," ",1) != 1) goto err;
-                                       }
-                               l=ll;
-                               }
                        i=s-c;
                        if (BIO_write(bp,c,i) != i) goto err;
                        c+=i;
index ff2f77b..66d229b 100644 (file)
@@ -93,7 +93,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
                                int tag, int aclass, char opt, ASN1_TLC *ctx);
 
 /* Table to convert tags to bit values, used for MSTRING type */
-static unsigned long tag2bit[32] = {
+static const unsigned long tag2bit[32] = {
 0,     0,      0,      B_ASN1_BIT_STRING,      /* tags  0 -  3 */
 B_ASN1_OCTET_STRING,   0,      0,              B_ASN1_UNKNOWN,/* tags  4- 7 */
 B_ASN1_UNKNOWN,        B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags  8-11 */
index 12d1a25..e118696 100644 (file)
@@ -94,6 +94,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
                ret->ex_pathlen = -1;
                ret->skid = NULL;
                ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+               ret->rfc3779_addr = NULL;
+               ret->rfc3779_asid = NULL;
+#endif
                ret->aux = NULL;
                CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
                break;
@@ -109,6 +113,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
                ASN1_OCTET_STRING_free(ret->skid);
                AUTHORITY_KEYID_free(ret->akid);
                policy_cache_free(ret->policy_cache);
+#ifndef OPENSSL_NO_RFC3779
+               sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
+               ASIdentifiers_free(ret->rfc3779_asid);
+#endif
 
                if (ret->name != NULL) OPENSSL_free(ret->name);
                break;
index 3419916..1607cef 100644 (file)
@@ -65,7 +65,7 @@
  * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
  */
 
-const char *BF_version="Blowfish" OPENSSL_VERSION_PTEXT;
+const char BF_version[]="Blowfish" OPENSSL_VERSION_PTEXT;
 
 const char *BF_options(void)
        {
index 07333cf..2c9e8a7 100644 (file)
@@ -196,28 +196,32 @@ extern "C" {
  */
 #define BIO_FLAGS_MEM_RDONLY   0x200
 
-#define BIO_set_flags(b,f) ((b)->flags|=(f))
-#define BIO_get_flags(b) ((b)->flags)
+typedef struct bio_st BIO;
+
+void BIO_set_flags(BIO *b, int flags);
+int  BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
 #define BIO_set_retry_special(b) \
-               ((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+               BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
 #define BIO_set_retry_read(b) \
-               ((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+               BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
 #define BIO_set_retry_write(b) \
-               ((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+               BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
 
 /* These are normally used internally in BIOs */
-#define BIO_clear_flags(b,f) ((b)->flags&= ~(f))
 #define BIO_clear_retry_flags(b) \
-               ((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+               BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
 #define BIO_get_retry_flags(b) \
-               ((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+               BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
 
 /* These should be used by the application to tell why we should retry */
-#define BIO_should_read(a)             ((a)->flags & BIO_FLAGS_READ)
-#define BIO_should_write(a)            ((a)->flags & BIO_FLAGS_WRITE)
-#define BIO_should_io_special(a)       ((a)->flags & BIO_FLAGS_IO_SPECIAL)
-#define BIO_retry_type(a)              ((a)->flags & BIO_FLAGS_RWS)
-#define BIO_should_retry(a)            ((a)->flags & BIO_FLAGS_SHOULD_RETRY)
+#define BIO_should_read(a)             BIO_test_flags(a, BIO_FLAGS_READ)
+#define BIO_should_write(a)            BIO_test_flags(a, BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a)       BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a)              BIO_test_flags(a, BIO_FLAGS_RWS)
+#define BIO_should_retry(a)            BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
 
 /* The next three are used in conjunction with the
  * BIO_should_io_special() condition.  After this returns true,
@@ -246,14 +250,14 @@ extern "C" {
 #define BIO_cb_pre(a)  (!((a)&BIO_CB_RETURN))
 #define BIO_cb_post(a) ((a)&BIO_CB_RETURN)
 
-#define BIO_set_callback(b,cb)         ((b)->callback=(cb))
-#define BIO_set_callback_arg(b,arg)    ((b)->cb_arg=(char *)(arg))
-#define BIO_get_callback_arg(b)                ((b)->cb_arg)
-#define BIO_get_callback(b)            ((b)->callback)
-#define BIO_method_name(b)             ((b)->method->name)
-#define BIO_method_type(b)             ((b)->method->type)
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long);
+void BIO_set_callback(BIO *b, 
+       long (*callback)(struct bio_st *,int,const char *,int, long,long));
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
 
-typedef struct bio_st BIO;
+const char * BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
 
 typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
 
@@ -386,6 +390,7 @@ typedef struct bio_f_buffer_ctx_struct
 #define BIO_C_NWRITE0                          145
 #define BIO_C_NWRITE                           146
 #define BIO_C_RESET_READ_REQUEST               147
+#define BIO_C_SET_MD_CTX                       148
 
 
 #define BIO_set_app_data(s,arg)                BIO_set_ex_data(s,0,arg)
index 426f8d1..6603f1c 100644 (file)
@@ -143,15 +143,12 @@ static ERR_STRING_DATA BIO_str_reasons[]=
 
 void ERR_load_BIO_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(BIO_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,BIO_str_functs);
                ERR_load_strings(0,BIO_str_reasons);
-#endif
-
                }
+#endif
        }
index dcc989f..3f52ae9 100644 (file)
@@ -141,6 +141,52 @@ int BIO_free(BIO *a)
 void BIO_vfree(BIO *a)
     { BIO_free(a); }
 
+void BIO_clear_flags(BIO *b, int flags)
+       {
+       b->flags &= ~flags;
+       }
+
+int    BIO_test_flags(const BIO *b, int flags)
+       {
+       return (b->flags & flags);
+       }
+
+void   BIO_set_flags(BIO *b, int flags)
+       {
+       b->flags |= flags;
+       }
+
+long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long)
+       {
+       return b->callback;
+       }
+
+void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long))
+       {
+       b->callback = cb;
+       }
+
+void BIO_set_callback_arg(BIO *b, char *arg)
+       {
+       b->cb_arg = arg;
+       }
+
+char * BIO_get_callback_arg(const BIO *b)
+       {
+       return b->cb_arg;
+       }
+
+const char * BIO_method_name(const BIO *b)
+       {
+       return b->method->name;
+       }
+
+int BIO_method_type(const BIO *b)
+       {
+       return b->method->type;
+       }
+
+
 int BIO_read(BIO *b, void *out, int outl)
        {
        int i;
index a253959..24fbbb7 100644 (file)
@@ -137,15 +137,12 @@ static ERR_STRING_DATA BN_str_reasons[]=
 
 void ERR_load_BN_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(BN_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,BN_str_functs);
                ERR_load_strings(0,BN_str_reasons);
-#endif
-
                }
+#endif
        }
index 3c4d545..210ccb4 100644 (file)
@@ -67,7 +67,7 @@
 #include "cryptlib.h"
 #include "bn_lcl.h"
 
-const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
+const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
 
 /* This stuff appears to be completely unused, so is deprecated */
 #ifndef OPENSSL_NO_DEPRECATED
index 055d048..810dde3 100644 (file)
@@ -62,7 +62,7 @@
 #include <openssl/buffer.h>
 #include "bn_lcl.h"
 
-static const char *Hex="0123456789ABCDEF";
+static const char Hex[]="0123456789ABCDEF";
 
 /* Must 'OPENSSL_free' the returned data */
 char *BN_bn2hex(const BIGNUM *a)
index 8fc67d3..3e25bbe 100644 (file)
@@ -88,15 +88,12 @@ static ERR_STRING_DATA BUF_str_reasons[]=
 
 void ERR_load_BUF_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(BUF_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,BUF_str_functs);
                ERR_load_strings(0,BUF_str_reasons);
-#endif
-
                }
+#endif
        }
index 6350546..491c26b 100644 (file)
 #include "camellia.h"
 #include "cmll_locl.h"
 
-/*
- * must be defined uint32_t
- */
-
 /* key constants */
-
 #define CAMELLIA_SIGMA1L (0xA09E667FL)
 #define CAMELLIA_SIGMA1R (0x3BCC908BL)
 #define CAMELLIA_SIGMA2L (0xB67AE858L)
  */
 
 /* e is pointer of subkey */
-#ifdef L_ENDIAN
-
-#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2 + 1])
-#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2])
-
-#else /* big endian */
-
 #define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
 #define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
 
-#endif /* IS_LITTLE_ENDIAN */
-
 /* rotation right shift 1byte */
 #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
 /* rotation left shift 1bit */
@@ -170,44 +156,6 @@ do                                                                 \
  * for speed up
  *
  */
-#if !defined(_MSC_VER)
-
-#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
-do                                                                     \
-       {                                                               \
-       t0 = kll;                                                       \
-       t2 = krr;                                                       \
-       t0 &= ll;                                                       \
-       t2 |= rr;                                                       \
-       rl ^= t2;                                                       \
-       lr ^= CAMELLIA_RL1(t0);                                         \
-       t3 = krl;                                                       \
-       t1 = klr;                                                       \
-       t3 &= rl;                                                       \
-       t1 |= lr;                                                       \
-       ll ^= t1;                                                       \
-       rr ^= CAMELLIA_RL1(t3);                                         \
-       } while(0)
-
-#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
-do                                                                     \
-       {                                                               \
-       ir =  CAMELLIA_SP1110(xr & 0xff);                               \
-       il =  CAMELLIA_SP1110((xl>>24) & 0xff);                         \
-       ir ^= CAMELLIA_SP0222((xr>>24) & 0xff);                         \
-       il ^= CAMELLIA_SP0222((xl>>16) & 0xff);                         \
-       ir ^= CAMELLIA_SP3033((xr>>16) & 0xff);                         \
-       il ^= CAMELLIA_SP3033((xl>>8) & 0xff);                          \
-       ir ^= CAMELLIA_SP4404((xr>>8) & 0xff);                          \
-       il ^= CAMELLIA_SP4404(xl & 0xff);                               \
-       il ^= kl;                                                       \
-       ir ^= il ^ kr;                                                  \
-       yl ^= ir;                                                       \
-       yr ^= CAMELLIA_RR8(il) ^ ir;                                    \
-       } while(0)
-
-#else /* for MS-VC */
-
 #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
 do                                                                     \
        {                                                               \
@@ -249,9 +197,8 @@ do                                                                  \
        yl ^= ir;                                                       \
        yr ^= il;                                                       \
        } while(0)
-#endif
 
-static const uint32_t camellia_sp1110[256] =
+static const u32 camellia_sp1110[256] =
        {
        0x70707000,0x82828200,0x2c2c2c00,0xececec00,
        0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
@@ -319,7 +266,7 @@ static const uint32_t camellia_sp1110[256] =
        0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
        };
 
-static const uint32_t camellia_sp0222[256] =
+static const u32 camellia_sp0222[256] =
        {
        0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
        0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
@@ -387,7 +334,7 @@ static const uint32_t camellia_sp0222[256] =
        0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
        };
 
-static const uint32_t camellia_sp3033[256] =
+static const u32 camellia_sp3033[256] =
        {
        0x38003838,0x41004141,0x16001616,0x76007676,
        0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
@@ -455,7 +402,7 @@ static const uint32_t camellia_sp3033[256] =
        0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
        };
 
-static const uint32_t camellia_sp4404[256] =
+static const u32 camellia_sp4404[256] =
        {
        0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
        0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
@@ -523,20 +470,19 @@ static const uint32_t camellia_sp4404[256] =
        0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
        };
 
-
 /**
  * Stuff related to the Camellia key schedule
  */
 #define subl(x) subL[(x)]
 #define subr(x) subR[(x)]
 
-void camellia_setup128(const unsigned char *key, uint32_t *subkey)
+void camellia_setup128(const u8 *key, u32 *subkey)
        {
-       uint32_t kll, klr, krl, krr;
-       uint32_t il, ir, t0, t1, w0, w1;
-       uint32_t kw4l, kw4r, dw, tl, tr;
-       uint32_t subL[26];
-       uint32_t subR[26];
+       u32 kll, klr, krl, krr;
+       u32 il, ir, t0, t1, w0, w1;
+       u32 kw4l, kw4r, dw, tl, tr;
+       u32 subL[26];
+       u32 subR[26];
 
        /**
         *  k == kll || klr || krl || krr (|| is concatination)
@@ -833,14 +779,14 @@ void camellia_setup128(const unsigned char *key, uint32_t *subkey)
        return;
        }
 
-void camellia_setup256(const unsigned char *key, uint32_t *subkey)
+void camellia_setup256(const u8 *key, u32 *subkey)
        {
-       uint32_t kll,klr,krl,krr;           /* left half of key */
-       uint32_t krll,krlr,krrl,krrr;       /* right half of key */
-       uint32_t il, ir, t0, t1, w0, w1;    /* temporary variables */
-       uint32_t kw4l, kw4r, dw, tl, tr;
-       uint32_t subL[34];
-       uint32_t subR[34];
+       u32 kll,klr,krl,krr;           /* left half of key */
+       u32 krll,krlr,krrl,krrr;       /* right half of key */
+       u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+       u32 kw4l, kw4r, dw, tl, tr;
+       u32 subL[34];
+       u32 subR[34];
 
        /**
         *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
@@ -1245,18 +1191,18 @@ void camellia_setup256(const unsigned char *key, uint32_t *subkey)
        return;
        }
 
-void camellia_setup192(const unsigned char *key, uint32_t *subkey)
+void camellia_setup192(const u8 *key, u32 *subkey)
        {
-       unsigned char kk[32];
-       uint32_t krll, krlr, krrl,krrr;
+       u8 kk[32];
+       u32 krll, krlr, krrl,krrr;
 
        memcpy(kk, key, 24);
-       memcpy((unsigned char *)&krll, key+16,4);
-       memcpy((unsigned char *)&krlr, key+20,4);
+       memcpy((u8 *)&krll, key+16,4);
+       memcpy((u8 *)&krlr, key+20,4);
        krrl = ~krll;
        krrr = ~krlr;
-       memcpy(kk+24, (unsigned char *)&krrl, 4);
-       memcpy(kk+28, (unsigned char *)&krrr, 4);
+       memcpy(kk+24, (u8 *)&krrl, 4);
+       memcpy(kk+28, (u8 *)&krrr, 4);
        camellia_setup256(kk, subkey);
        return;
        }
@@ -1265,11 +1211,10 @@ void camellia_setup192(const unsigned char *key, uint32_t *subkey)
 /**
  * Stuff related to camellia encryption/decryption
  */
-void camellia_encrypt128(const uint32_t *subkey, uint32_t *io)
+void camellia_encrypt128(const u32 *subkey, u32 *io)
        {
-       uint32_t il, ir, t0, t1;
+       u32 il, ir, t0, t1;
 
-       SWAP4WORD(io);
        /* pre whitening but absorb kw2*/
        io[0] ^= CamelliaSubkeyL(0);
        io[1] ^= CamelliaSubkeyR(0);
@@ -1352,16 +1297,13 @@ void camellia_encrypt128(const uint32_t *subkey, uint32_t *io)
        io[1] = io[3];
        io[2] = t0;
        io[3] = t1;
-       SWAP4WORD(io);
-       
+
        return;
        }
 
-void camellia_decrypt128(const uint32_t *subkey, uint32_t *io)
+void camellia_decrypt128(const u32 *subkey, u32 *io)
        {
-       uint32_t il,ir,t0,t1;               /* temporary valiables */
-    
-       SWAP4WORD(io);
+       u32 il,ir,t0,t1;               /* temporary valiables */
 
        /* pre whitening but absorb kw2*/
        io[0] ^= CamelliaSubkeyL(24);
@@ -1445,7 +1387,6 @@ void camellia_decrypt128(const uint32_t *subkey, uint32_t *io)
        io[1] = io[3];
        io[2] = t0;
        io[3] = t1;
-       SWAP4WORD(io);
 
        return;
        }
@@ -1453,11 +1394,9 @@ void camellia_decrypt128(const uint32_t *subkey, uint32_t *io)
 /**
  * stuff for 192 and 256bit encryption/decryption
  */
-void camellia_encrypt256(const uint32_t *subkey, uint32_t *io)
+void camellia_encrypt256(const u32 *subkey, u32 *io)
        {
-       uint32_t il,ir,t0,t1;           /* temporary valiables */
-
-       SWAP4WORD(io);
+       u32 il,ir,t0,t1;           /* temporary valiables */
 
        /* pre whitening but absorb kw2*/
        io[0] ^= CamelliaSubkeyL(0);
@@ -1565,16 +1504,14 @@ void camellia_encrypt256(const uint32_t *subkey, uint32_t *io)
        io[1] = io[3];
        io[2] = t0;
        io[3] = t1;
-       SWAP4WORD(io);
 
        return;
        }
 
-void camellia_decrypt256(const uint32_t *subkey, uint32_t *io)
+void camellia_decrypt256(const u32 *subkey, u32 *io)
        {
-       uint32_t il,ir,t0,t1;           /* temporary valiables */
+       u32 il,ir,t0,t1;           /* temporary valiables */
 
-       SWAP4WORD(io);
        /* pre whitening but absorb kw2*/
        io[0] ^= CamelliaSubkeyL(32);
        io[1] ^= CamelliaSubkeyR(32);
@@ -1681,7 +1618,6 @@ void camellia_decrypt256(const uint32_t *subkey, uint32_t *io)
        io[1] = io[3];
        io[2] = t0;
        io[3] = t1;
-       SWAP4WORD(io);
 
        return;
        }
index 24080e1..4141a7b 100644 (file)
@@ -67,25 +67,28 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
 
        unsigned long n;
        unsigned long len = length;
-       unsigned char tmp[CAMELLIA_BLOCK_SIZE];
        const unsigned char *iv = ivec;
-       uint32_t t32[UNITSIZE];
+       union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
+               u8  t8 [CAMELLIA_BLOCK_SIZE]; } tmp;
+       const union { long one; char little; } camellia_endian = {1};
 
 
        assert(in && out && key && ivec);
        assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
 
-       if(((size_t)in) % ALIGN == 0
-               && ((size_t)out) % ALIGN == 0
-               && ((size_t)ivec) % ALIGN == 0)
+       if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0)
                {
                if (CAMELLIA_ENCRYPT == enc)
                        {
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
-                               XOR4WORD2((uint32_t *)out,
-                                       (uint32_t *)in, (uint32_t *)iv);
-                               key->enc(key->rd_key, (uint32_t *)out);
+                               XOR4WORD2((u32 *)out,
+                                       (u32 *)in, (u32 *)iv);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               key->enc(key->rd_key, (u32 *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
                                iv = out;
                                len -= CAMELLIA_BLOCK_SIZE;
                                in += CAMELLIA_BLOCK_SIZE;
@@ -97,7 +100,11 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                                        out[n] = in[n] ^ iv[n];
                                for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
                                        out[n] = iv[n];
-                               key->enc(key->rd_key, (uint32_t *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               key->enc(key->rd_key, (u32 *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
                                iv = out;
                                }
                        memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
@@ -107,8 +114,12 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
                                memcpy(out,in,CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key,(uint32_t *)out);
-                               XOR4WORD((uint32_t *)out, (uint32_t *)iv);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               key->dec(key->rd_key,(u32 *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               XOR4WORD((u32 *)out, (u32 *)iv);
                                iv = in;
                                len -= CAMELLIA_BLOCK_SIZE;
                                in  += CAMELLIA_BLOCK_SIZE;
@@ -116,10 +127,14 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                                }
                        if (len)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key, (uint32_t *)tmp);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->dec(key->rd_key, tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
                                for(n=0; n < len; ++n)
-                                       out[n] = tmp[n] ^ iv[n];
+                                       out[n] = tmp.t8[n] ^ iv[n];
                                iv = in;
                                }
                        memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
@@ -128,23 +143,31 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        {
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key, (uint32_t *)out);
-                               XOR4WORD((uint32_t *)out, (uint32_t *)ivec);
-                               memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               key->dec(key->rd_key, (u32 *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               XOR4WORD((u32 *)out, (u32 *)ivec);
+                               memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
                                len -= CAMELLIA_BLOCK_SIZE;
                                in += CAMELLIA_BLOCK_SIZE;
                                out += CAMELLIA_BLOCK_SIZE;
                                }
                        if (len)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key,(uint32_t *)out);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
+                               key->dec(key->rd_key,(u32 *)out);
+                               if (camellia_endian.little)
+                                       SWAP4WORD((u32 *)out);
                                for(n=0; n < len; ++n)
                                        out[n] ^= ivec[n];
                                for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] = tmp[n];
-                               memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
+                                       out[n] = tmp.t8[n];
+                               memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
                                }
                        }
                }
@@ -155,10 +178,13 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
                                for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] = in[n] ^ iv[n];
-                               memcpy(t32, out, CAMELLIA_BLOCK_SIZE);
-                               key->enc(key->rd_key, t32);
-                               memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
+                                       tmp.t8[n] = in[n] ^ iv[n];
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->enc(key->rd_key, tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
                                iv = out;
                                len -= CAMELLIA_BLOCK_SIZE;
                                in += CAMELLIA_BLOCK_SIZE;
@@ -167,10 +193,15 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        if (len)
                                {
                                for(n=0; n < len; ++n)
-                                       out[n] = in[n] ^ iv[n];
+                                       tmp.t8[n] = in[n] ^ iv[n];
                                for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] = iv[n];
-                               key->enc(key->rd_key, (uint32_t *)out);
+                                       tmp.t8[n] = iv[n];
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->enc(key->rd_key, tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
                                iv = out;
                                }
                        memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
@@ -179,11 +210,14 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        {
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
-                               memcpy(t32,in,CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key,t32);
-                               memcpy(out,t32,CAMELLIA_BLOCK_SIZE);
+                               memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->dec(key->rd_key,tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
                                for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] ^= iv[n];
+                                       out[n] = tmp.t8[n] ^ iv[n];
                                iv = in;
                                len -= CAMELLIA_BLOCK_SIZE;
                                in  += CAMELLIA_BLOCK_SIZE;
@@ -191,12 +225,14 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                                }
                        if (len)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key, t32);
-                               memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->dec(key->rd_key, tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
                                for(n=0; n < len; ++n)
-                                       out[n] = tmp[n] ^ iv[n];
+                                       out[n] = tmp.t8[n] ^ iv[n];
                                iv = in;
                                }
                        memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
@@ -205,30 +241,33 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        {
                        while (len >= CAMELLIA_BLOCK_SIZE)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key, t32);
-                               memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->dec(key->rd_key, tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
                                for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] ^= ivec[n];
-                               memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
+                                       tmp.t8[n] ^= ivec[n];
+                               memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
+                               memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
                                len -= CAMELLIA_BLOCK_SIZE;
                                in += CAMELLIA_BLOCK_SIZE;
                                out += CAMELLIA_BLOCK_SIZE;
                                }
                        if (len)
                                {
-                               memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-                               memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
-                               key->dec(key->rd_key,t32);
-                               memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
+                               memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
+                               key->dec(key->rd_key,tmp.t32);
+                               if (camellia_endian.little)
+                                       SWAP4WORD(tmp.t32);
                                for(n=0; n < len; ++n)
-                                       out[n] ^= ivec[n];
-                               for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-                                       out[n] = tmp[n];
-                               memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
+                                       tmp.t8[n] ^= ivec[n];
+                               memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
+                               memcpy(out,tmp.t8,len);
                                }
                        }
                }
 }
-
index 8ea3639..2ac2e95 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#if defined(_MSC_VER)
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef unsigned __int64 uint64_t;
-#else
-#include <inttypes.h>
-#endif
+typedef unsigned char u8;
+typedef unsigned int u32;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define ALIGN 4
-#define UNITSIZE 4
-
 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
 # define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 )
-# define GETU32(p) SWAP(*((uint32_t *)(p)))
-# define PUTU32(ct, st) { *((uint32_t *)(ct)) = SWAP((st)); }
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
 # define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) )
 
-
 #else /* not windows */
-# define GETU32(pt) (((uint32_t)(pt)[0] << 24) \
-       ^ ((uint32_t)(pt)[1] << 16) \
-       ^ ((uint32_t)(pt)[2] <<  8) \
-       ^ ((uint32_t)(pt)[3]))
-
-# define PUTU32(ct, st) { (ct)[0] = (uint8_t)((st) >> 24); \
-       (ct)[1] = (uint8_t)((st) >> 16); \
-       (ct)[2] = (uint8_t)((st) >>  8); \
-       (ct)[3] = (uint8_t)(st); }
-
-#ifdef L_ENDIAN
-#if (defined (__GNUC__) && !defined(i386))
+# define GETU32(pt) (((u32)(pt)[0] << 24) \
+       ^ ((u32)(pt)[1] << 16) \
+       ^ ((u32)(pt)[2] <<  8) \
+       ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \
+       (ct)[1] = (u8)((st) >> 16); \
+       (ct)[2] = (u8)((st) >>  8); \
+       (ct)[3] = (u8)(st); }
+
+#if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64)))
 #define CAMELLIA_SWAP4(x) \
   do{\
     asm("bswap %1" : "+r" (x));\
   }while(0)
-#else /* not gcc */
+#else
 #define CAMELLIA_SWAP4(x) \
    do{\
-     x = ((uint32_t)x << 16) + ((uint32_t)x >> 16);\
-     x = (((uint32_t)x & 0xff00ff) << 8) + (((uint32_t)x >> 8) & 0xff00ff);\
+     x = ((u32)x << 16) + ((u32)x >> 16);\
+     x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\
    } while(0)
-#endif /* not gcc */
-#else /* big endian */
-#define CAMELLIA_SWAP4(x)
-#endif /* L_ENDIAN */
+#endif
 #endif
 
 #define COPY4WORD(dst, src)     \
@@ -161,14 +148,14 @@ extern "C" {
        }while(0)
 
 
-void camellia_setup128(const unsigned char *key, uint32_t *subkey);
-void camellia_setup192(const unsigned char *key, uint32_t *subkey);
-void camellia_setup256(const unsigned char *key, uint32_t *subkey);
+void camellia_setup128(const u8 *key, u32 *subkey);
+void camellia_setup192(const u8 *key, u32 *subkey);
+void camellia_setup256(const u8 *key, u32 *subkey);
 
-void camellia_encrypt128(const uint32_t *subkey, uint32_t *io);
-void camellia_decrypt128(const uint32_t *subkey, uint32_t *io);
-void camellia_encrypt256(const uint32_t *subkey, uint32_t *io);
-void camellia_decrypt256(const uint32_t *subkey, uint32_t *io);
+void camellia_encrypt128(const u32 *subkey, u32 *io);
+void camellia_decrypt128(const u32 *subkey, u32 *io);
+void camellia_encrypt256(const u32 *subkey, u32 *io);
+void camellia_decrypt256(const u32 *subkey, u32 *io);
 
 #ifdef __cplusplus
 }
index 3c4ec36..f1047b5 100644 (file)
@@ -53,7 +53,7 @@
 #include <openssl/camellia.h>
 #include "cmll_locl.h"
 
-const char *CAMELLIA_version="CAMELLIA" OPENSSL_VERSION_PTEXT;
+const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
 
 int Camellia_set_key(const unsigned char *userKey, const int bits,
        CAMELLIA_KEY *key)
@@ -91,20 +91,26 @@ int Camellia_set_key(const unsigned char *userKey, const int bits,
 void Camellia_encrypt(const unsigned char *in, unsigned char *out,
        const CAMELLIA_KEY *key)
        {
-       uint32_t tmp[UNITSIZE];
+       u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
+       const union { long one; char little; } camellia_endian = {1};
 
        memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+       if (camellia_endian.little) SWAP4WORD(tmp);
        key->enc(key->rd_key, tmp);
+       if (camellia_endian.little) SWAP4WORD(tmp);
        memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
        }
 
 void Camellia_decrypt(const unsigned char *in, unsigned char *out,
        const CAMELLIA_KEY *key)
        {
-       uint32_t tmp[UNITSIZE];
+       u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
+       const union { long one; char little; } camellia_endian = {1};
 
        memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+       if (camellia_endian.little) SWAP4WORD(tmp);
        key->dec(key->rd_key, tmp);
+       if (camellia_endian.little) SWAP4WORD(tmp);
        memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
        }
 
index 0b3da9a..f2dc606 100644 (file)
@@ -60,7 +60,7 @@
 #include "cast_lcl.h"
 #include <openssl/opensslv.h>
 
-const char *CAST_version="CAST" OPENSSL_VERSION_PTEXT;
+const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT;
 
 void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
                      CAST_KEY *ks, int enc)
index 941b807..43402e7 100644 (file)
@@ -31,6 +31,24 @@ static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
        unsigned int olen, unsigned char *in, unsigned int ilen);
 
+
+/* memory allocations functions for zlib intialization */
+static void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
+{
+       void *p;
+       
+       p=OPENSSL_malloc(no*size);
+       if (p)
+               memset(p, 0, no*size);
+       return p;
+}
+
+
+static void zlib_zfree(void* opaque, void* address)
+{
+       OPENSSL_free(address);
+}
+
 #if 0
 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
        unsigned int olen, unsigned char *in, unsigned int ilen);
@@ -133,8 +151,8 @@ static int zlib_stateful_init(COMP_CTX *ctx)
        if (state == NULL)
                goto err;
 
-       state->istream.zalloc = Z_NULL;
-       state->istream.zfree = Z_NULL;
+       state->istream.zalloc = zlib_zalloc;
+       state->istream.zfree = zlib_zfree;
        state->istream.opaque = Z_NULL;
        state->istream.next_in = Z_NULL;
        state->istream.next_out = Z_NULL;
@@ -145,8 +163,8 @@ static int zlib_stateful_init(COMP_CTX *ctx)
        if (err != Z_OK)
                goto err;
 
-       state->ostream.zalloc = Z_NULL;
-       state->ostream.zfree = Z_NULL;
+       state->ostream.zalloc = zlib_zalloc;
+       state->ostream.zfree = zlib_zfree;
        state->ostream.opaque = Z_NULL;
        state->ostream.next_in = Z_NULL;
        state->ostream.next_out = Z_NULL;
@@ -158,17 +176,6 @@ static int zlib_stateful_init(COMP_CTX *ctx)
                goto err;
 
        CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
-       if (zlib_stateful_ex_idx == -1)
-               {
-               CRYPTO_w_lock(CRYPTO_LOCK_COMP);
-               if (zlib_stateful_ex_idx == -1)
-                       zlib_stateful_ex_idx =
-                               CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
-                                       0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
-               CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
-               if (zlib_stateful_ex_idx == -1)
-                       goto err;
-               }
        CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
        return 1;
  err:
@@ -379,7 +386,25 @@ COMP_METHOD *COMP_zlib(void)
        if (zlib_loaded)
 #endif
 #if defined(ZLIB) || defined(ZLIB_SHARED)
+               {
+               /* init zlib_stateful_ex_idx here so that in a multi-process
+                * application it's enough to intialize openssl before forking
+                * (idx will be inherited in all the children) */
+               if (zlib_stateful_ex_idx == -1)
+                       {
+                       CRYPTO_w_lock(CRYPTO_LOCK_COMP);
+                       if (zlib_stateful_ex_idx == -1)
+                               zlib_stateful_ex_idx =
+                                       CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
+                                               0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
+                       CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
+                       if (zlib_stateful_ex_idx == -1)
+                               goto err;
+                       }
+               
                meth = &zlib_stateful_method;
+               }
+err:   
 #endif
 
        return(meth);
index bf7aa3a..0737222 100644 (file)
@@ -82,15 +82,12 @@ static ERR_STRING_DATA COMP_str_reasons[]=
 
 void ERR_load_COMP_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(COMP_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,COMP_str_functs);
                ERR_load_strings(0,COMP_str_reasons);
-#endif
-
                }
+#endif
        }
index 8083a00..d8bce87 100644 (file)
@@ -88,7 +88,7 @@ static int def_dump(const CONF *conf, BIO *bp);
 static int def_is_number(const CONF *conf, char c);
 static int def_to_int(const CONF *conf, char c);
 
-const char *CONF_def_version="CONF_def" OPENSSL_VERSION_PTEXT;
+const char CONF_def_version[]="CONF_def" OPENSSL_VERSION_PTEXT;
 
 static CONF_METHOD default_method = {
        "OpenSSL default",
index 6250689..a16a5e0 100644 (file)
@@ -118,15 +118,12 @@ static ERR_STRING_DATA CONF_str_reasons[]=
 
 void ERR_load_CONF_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(CONF_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,CONF_str_functs);
                ERR_load_strings(0,CONF_str_reasons);
-#endif
-
                }
+#endif
        }
index a55a545..2a3399d 100644 (file)
@@ -63,7 +63,7 @@
 #include <openssl/conf_api.h>
 #include <openssl/lhash.h>
 
-const char *CONF_version="CONF" OPENSSL_VERSION_PTEXT;
+const char CONF_version[]="CONF" OPENSSL_VERSION_PTEXT;
 
 static CONF_METHOD *default_CONF_method=NULL;
 
index 06a6109..9fd41ff 100644 (file)
@@ -92,15 +92,12 @@ static ERR_STRING_DATA CRYPTO_str_reasons[]=
 
 void ERR_load_CRYPTO_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,CRYPTO_str_functs);
                ERR_load_strings(0,CRYPTO_str_reasons);
-#endif
-
                }
+#endif
        }
index 315559c..86af760 100644 (file)
@@ -125,7 +125,7 @@ DECLARE_STACK_OF(CRYPTO_dynlock)
 IMPLEMENT_STACK_OF(CRYPTO_dynlock)
 
 /* real #defines in crypto.h, keep these upto date */
-static const char* lock_names[CRYPTO_NUM_LOCKS] =
+static const char* const lock_names[CRYPTO_NUM_LOCKS] =
        {
        "<<ERROR>>",
        "err",
index 379bbad..d1ada25 100644 (file)
@@ -67,5 +67,5 @@
 #define DES_version OSSL_DES_version
 #define libdes_version OSSL_libdes_version
 
-OPENSSL_EXTERN const char *OSSL_DES_version;   /* SSLeay version string */
-OPENSSL_EXTERN const char *OSSL_libdes_version;        /* old libdes version string */
+OPENSSL_EXTERN const char OSSL_DES_version[];  /* SSLeay version string */
+OPENSSL_EXTERN const char OSSL_libdes_version[];       /* old libdes version string */
index 784aa5b..00d5b91 100644 (file)
@@ -62,8 +62,8 @@
 #include <openssl/opensslv.h>
 #include <openssl/bio.h>
 
-OPENSSL_GLOBAL const char *libdes_version="libdes" OPENSSL_VERSION_PTEXT;
-OPENSSL_GLOBAL const char *DES_version="DES" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
 
 const char *DES_options(void)
        {
index 783bb47..a2d8196 100644 (file)
@@ -93,15 +93,12 @@ static ERR_STRING_DATA DH_str_reasons[]=
 
 void ERR_load_DH_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(DH_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,DH_str_functs);
                ERR_load_strings(0,DH_str_reasons);
-#endif
-
                }
+#endif
        }
index cb5abdc..37a2c1b 100644 (file)
@@ -173,7 +173,7 @@ err:
 
 static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
        {
-       BN_CTX *ctx;
+       BN_CTX *ctx=NULL;
        BN_MONT_CTX *mont=NULL;
        BIGNUM *tmp;
        int ret= -1;
index 09965ee..7aef080 100644 (file)
@@ -64,7 +64,7 @@
 #include <openssl/engine.h>
 #endif
 
-const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
+const char DH_version[]="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
 
 static const DH_METHOD *default_DH_method = NULL;
 
index d7fac69..7687119 100644 (file)
@@ -100,15 +100,12 @@ static ERR_STRING_DATA DSA_str_reasons[]=
 
 void ERR_load_DSA_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(DSA_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,DSA_str_functs);
                ERR_load_strings(0,DSA_str_reasons);
-#endif
-
                }
+#endif
        }
index b982579..e9b7590 100644 (file)
@@ -70,7 +70,7 @@
 #include <openssl/dh.h>
 #endif
 
-const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT;
+const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
 
 static const DSA_METHOD *default_DSA_method = NULL;
 
index aa91170..a8b0a21 100644 (file)
@@ -136,15 +136,12 @@ static ERR_STRING_DATA DSO_str_reasons[]=
 
 void ERR_load_DSO_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(DSO_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,DSO_str_functs);
                ERR_load_strings(0,DSO_str_reasons);
-#endif
-
                }
+#endif
        }
index 66ef129..ae55539 100644 (file)
@@ -529,6 +529,8 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
                                ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
                                goto err;
                                }
+               curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+               curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
                if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 
                                         (int)group->seed_len))
                        {
@@ -1291,6 +1293,8 @@ int       i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
                        goto err;
                        }
 
+               priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+               priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
                if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 
                                buf_len))
                        {
index 031c54d..7be315b 100644 (file)
@@ -227,15 +227,12 @@ static ERR_STRING_DATA EC_str_reasons[]=
 
 void ERR_load_EC_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,EC_str_functs);
                ERR_load_strings(0,EC_str_reasons);
-#endif
-
                }
+#endif
        }
index 626f49b..4d2ede7 100644 (file)
@@ -71,7 +71,7 @@
 static ERR_STRING_DATA ECDH_str_functs[]=
        {
 {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY),    "ECDH_compute_key"},
-{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),        "ECDH_DATA_new_method"},
+{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),        "ECDH_DATA_NEW_METHOD"},
 {0,NULL}
        };
 
@@ -87,15 +87,12 @@ static ERR_STRING_DATA ECDH_str_reasons[]=
 
 void ERR_load_ECDH_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,ECDH_str_functs);
                ERR_load_strings(0,ECDH_str_reasons);
-#endif
-
                }
+#endif
        }
index 01e75e2..e89b1d4 100644 (file)
@@ -74,7 +74,7 @@
 #endif
 #include <openssl/err.h>
 
-const char *ECDH_version="ECDH" OPENSSL_VERSION_PTEXT;
+const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
 
 static const ECDH_METHOD *default_ECDH_method = NULL;
 
index 76c5a4a..f20c8ee 100644 (file)
@@ -261,6 +261,7 @@ void ERR_load_ECDSA_strings(void);
 #define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE             101
 #define ECDSA_R_ERR_EC_LIB                              102
 #define ECDSA_R_MISSING_PARAMETERS                      103
+#define ECDSA_R_NEED_NEW_SETUP_VALUES                   106
 #define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED                 104
 #define ECDSA_R_SIGNATURE_MALLOC_FAILED                         105
 
index 90f1942..d2a5373 100644 (file)
@@ -70,7 +70,7 @@
 
 static ERR_STRING_DATA ECDSA_str_functs[]=
        {
-{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD),      "ECDSA_DATA_new_method"},
+{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD),      "ECDSA_DATA_NEW_METHOD"},
 {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN),      "ECDSA_do_sign"},
 {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY),    "ECDSA_do_verify"},
 {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP),   "ECDSA_sign_setup"},
@@ -83,6 +83,7 @@ static ERR_STRING_DATA ECDSA_str_reasons[]=
 {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
 {ERR_REASON(ECDSA_R_ERR_EC_LIB)          ,"err ec lib"},
 {ERR_REASON(ECDSA_R_MISSING_PARAMETERS)  ,"missing parameters"},
+{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"},
 {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
 {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
 {0,NULL}
@@ -92,15 +93,12 @@ static ERR_STRING_DATA ECDSA_str_reasons[]=
 
 void ERR_load_ECDSA_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,ECDSA_str_functs);
                ERR_load_strings(0,ECDSA_str_reasons);
-#endif
-
                }
+#endif
        }
index 1fb9bc9..85e8a3a 100644 (file)
@@ -61,7 +61,7 @@
 #include <openssl/err.h>
 #include <openssl/bn.h>
 
-const char *ECDSA_version="ECDSA" OPENSSL_VERSION_PTEXT;
+const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
 
 static const ECDSA_METHOD *default_ECDSA_method = NULL;
 
index 8be45dd..32d66a9 100644 (file)
@@ -299,8 +299,21 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
                        ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
                        goto err;
                }
+               if (BN_is_zero(s))
+               {
+                       /* if kinv and r have been supplied by the caller
+                        * don't to generate new kinv and r values */
+                       if (in_kinv != NULL && in_r != NULL)
+                       {
+                               ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
+                               goto err;
+                       }
+               }
+               else
+                       /* s != 0 => we have a valid signature */
+                       break;
        }
-       while (BN_is_zero(s));
+       while (1);
 
        ok = 1;
 err:
index 86b2f9a..8599046 100644 (file)
@@ -67,6 +67,9 @@ void ENGINE_load_builtin_engines(void)
         * *no* builtin implementations). */
 #if 0
        ENGINE_load_openssl();
+#endif
+#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
+       ENGINE_load_padlock();
 #endif
        ENGINE_load_dynamic();
 #ifndef OPENSSL_NO_STATIC_ENGINE
@@ -95,16 +98,15 @@ void ENGINE_load_builtin_engines(void)
 #ifndef OPENSSL_NO_HW_UBSEC
        ENGINE_load_ubsec();
 #endif
-#ifndef OPENSSL_NO_HW_PADLOCK
-       ENGINE_load_padlock();
+#endif
+#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
+       ENGINE_load_gmp();
 #endif
 #endif
+#ifndef OPENSSL_NO_HW
 #if defined(__OpenBSD__) || defined(__FreeBSD__)
        ENGINE_load_cryptodev();
 #endif
-#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
-       ENGINE_load_gmp();
-#endif
 #endif
        }
 
index 62db507..369f2e2 100644 (file)
@@ -157,15 +157,12 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
 
 void ERR_load_ENGINE_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,ENGINE_str_functs);
                ERR_load_strings(0,ENGINE_str_reasons);
-#endif
-
                }
+#endif
        }
index 8d92af6..e1d66ea 100644 (file)
@@ -436,8 +436,8 @@ static inline void *name(size_t cnt,                \
                        rep_xcrypt "\n"         \
                "       popl    %%ebx"          \
                : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
-               : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
-               : "edx", "cc");                 \
+               : "0"(cdata), "1"(cnt), "2"(out), "3"(inp), "m"(*cdata)  \
+               : "edx", "cc", "memory");       \
        return iv;                              \
 }
 
index 59977f7..c8ec781 100644 (file)
@@ -107,7 +107,7 @@ int ENGINE_set_default_ECDH(ENGINE *e)
        {
        if(e->ecdh_meth)
                return engine_table_register(&ecdh_table,
-                               engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
+                               engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
        return 1;
        }
 
index e30b02e..005ecb6 100644 (file)
@@ -92,7 +92,7 @@ int ENGINE_set_default_ECDSA(ENGINE *e)
        {
        if(e->ecdsa_meth)
                return engine_table_register(&ecdsa_table,
-                               engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
+                               engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
        return 1;
        }
 
index bfb4c1a..c33d24b 100644 (file)
 
 void ERR_load_crypto_strings(void)
        {
-       static int done=0;
-
-       if (done) return;
-       done=1;
 #ifndef OPENSSL_NO_ERR
        ERR_load_ERR_strings(); /* include error strings for SYSerr */
        ERR_load_BN_strings();
index 76ff9fe..d648ac6 100644 (file)
@@ -200,6 +200,12 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
                else
                        ret=0;
                break;
+       case BIO_C_SET_MD_CTX:
+               if (b->init)
+                       b->ptr=ptr;
+               else
+                       ret=0;
+               break;
        case BIO_C_DO_STATE_MACHINE:
                BIO_clear_retry_flags(b);
                ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
index 1b09bd8..636f426 100644 (file)
@@ -429,36 +429,36 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
 #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
 #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
 
-#define EVP_MD_type(e)                 ((e)->type)
+int EVP_MD_type(const EVP_MD *md);
 #define EVP_MD_nid(e)                  EVP_MD_type(e)
 #define EVP_MD_name(e)                 OBJ_nid2sn(EVP_MD_nid(e))
-#define EVP_MD_pkey_type(e)            ((e)->pkey_type)
-#define EVP_MD_size(e)                 ((e)->md_size)
-#define EVP_MD_block_size(e)           ((e)->block_size)
+int EVP_MD_pkey_type(const EVP_MD *md);        
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
 
-#define EVP_MD_CTX_md(e)               ((e)->digest)
-#define EVP_MD_CTX_size(e)             EVP_MD_size((e)->digest)
-#define EVP_MD_CTX_block_size(e)       EVP_MD_block_size((e)->digest)
-#define EVP_MD_CTX_type(e)             EVP_MD_type((e)->digest)
+const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+#define EVP_MD_CTX_size(e)             EVP_MD_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_block_size(e)       EVP_MD_block_size(EVP_MD_CTX_md(e))
+#define EVP_MD_CTX_type(e)             EVP_MD_type(EVP_MD_CTX_md(e))
 
-#define EVP_CIPHER_nid(e)              ((e)->nid)
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
 #define EVP_CIPHER_name(e)             OBJ_nid2sn(EVP_CIPHER_nid(e))
-#define EVP_CIPHER_block_size(e)       ((e)->block_size)
-#define EVP_CIPHER_key_length(e)       ((e)->key_len)
-#define EVP_CIPHER_iv_length(e)                ((e)->iv_len)
-#define EVP_CIPHER_flags(e)            ((e)->flags)
-#define EVP_CIPHER_mode(e)             (((e)->flags) & EVP_CIPH_MODE)
-
-#define EVP_CIPHER_CTX_cipher(e)       ((e)->cipher)
-#define EVP_CIPHER_CTX_nid(e)          ((e)->cipher->nid)
-#define EVP_CIPHER_CTX_block_size(e)   ((e)->cipher->block_size)
-#define EVP_CIPHER_CTX_key_length(e)   ((e)->key_len)
-#define EVP_CIPHER_CTX_iv_length(e)    ((e)->cipher->iv_len)
-#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
-#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+#define EVP_CIPHER_mode(e)             (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
 #define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
-#define EVP_CIPHER_CTX_flags(e)                ((e)->cipher->flags)
-#define EVP_CIPHER_CTX_mode(e)         ((e)->cipher->flags & EVP_CIPH_MODE)
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+#define EVP_CIPHER_CTX_mode(e)         (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
 
 #define EVP_ENCODE_LENGTH(l)   (((l+2)/3*4)+(l/48+1)*2+80)
 #define EVP_DECODE_LENGTH(l)   ((l+3)/4*3+80)
@@ -479,10 +479,14 @@ void BIO_set_md(BIO *,const EVP_MD *md);
 #endif
 #define BIO_get_md(b,mdp)              BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
 #define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
 #define BIO_get_cipher_status(b)       BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
 #define BIO_get_cipher_ctx(b,c_pp)     BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
 
-#define        EVP_Cipher(c,o,i,l)     (c)->cipher->do_cipher((c),(o),(i),(l))
+int EVP_Cipher(EVP_CIPHER_CTX *c,
+               unsigned char *out,
+               const unsigned char *in,
+               unsigned int inl);
 
 #define EVP_add_cipher_alias(n,alias) \
        OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
@@ -498,9 +502,9 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
 EVP_MD_CTX *EVP_MD_CTX_create(void);
 void   EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
 int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
-#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
-#define EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
-#define EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
+void   EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void   EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int    EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags);
 int    EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
 int    EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
                         size_t cnt);
index f0b725d..a190499 100644 (file)
@@ -66,7 +66,7 @@
 #endif
 #include "evp_locl.h"
 
-const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
+const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
 
 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
        {
index cb6d9fa..e8c9e8d 100644 (file)
@@ -163,15 +163,12 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 
 void ERR_load_EVP_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(EVP_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,EVP_str_functs);
                ERR_load_strings(0,EVP_str_reasons);
-#endif
-
                }
+#endif
        }
index 3621396..f92db23 100644 (file)
@@ -168,3 +168,112 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
        }
 }
 
+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+       {
+       return e->block_size;
+       }
+
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->block_size;
+       }
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
+       {
+       return ctx->cipher->do_cipher(ctx,out,in,inl);
+       }
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher;
+       }
+
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+       {
+       return cipher->flags;
+       }
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->flags;
+       }
+
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->app_data;
+       }
+
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+       {
+       ctx->app_data = data;
+       }
+
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
+       {
+       return cipher->iv_len;
+       }
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->iv_len;
+       }
+
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
+       {
+       return cipher->key_len;
+       }
+
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->key_len;
+       }
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+       {
+       return cipher->nid;
+       }
+
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->nid;
+       }
+
+int EVP_MD_block_size(const EVP_MD *md) 
+       {
+       return md->block_size;
+       }
+
+int EVP_MD_type(const EVP_MD *md)
+       {
+       return md->type;
+       }
+
+int EVP_MD_pkey_type(const EVP_MD *md)
+       {
+       return md->pkey_type;
+       }
+
+int EVP_MD_size(const EVP_MD *md)
+       {
+       return md->md_size;
+       }
+
+const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+       {
+       return ctx->digest;
+       }
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+       {
+       ctx->flags |= flags;
+       }
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+       {
+       ctx->flags &= ~flags;
+       }
+
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+       {
+       return (ctx->flags & flags);
+       }
index 2204e34..20139d2 100644 (file)
@@ -65,7 +65,7 @@
        bl = ctx->cipher->block_size;\
        if(inl < bl) return 1;\
        inl -= bl; \
-       for(i=0; i <= inl; i+=bl) \
+       for(i=0; i <= inl; i+=bl) 
 
 #define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
 static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
index fb613db..fef3823 100644 (file)
@@ -60,7 +60,7 @@
 #include "idea_lcl.h"
 #include <openssl/opensslv.h>
 
-const char *IDEA_version="IDEA" OPENSSL_VERSION_PTEXT;
+const char IDEA_version[]="IDEA" OPENSSL_VERSION_PTEXT;
 
 const char *idea_options(void)
        {
index 463aa36..f3dbfa6 100644 (file)
@@ -67,7 +67,7 @@ if (ul != 0) \
        r-=((r)>>16); \
        } \
 else \
-       r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ \
+       r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ 
 
 #ifdef undef
 #define idea_mul(r,a,b,ul,sl) \
index 55cb055..04ea802 100644 (file)
 #include <openssl/crypto.h>
 #include <openssl/lhash.h>
 
-const char *lh_version="lhash" OPENSSL_VERSION_PTEXT;
+const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT;
 
 #undef MIN_NODES 
 #define MIN_NODES      16
index 5b71855..a46120e 100644 (file)
@@ -63,6 +63,7 @@
 #ifdef OPENSSL_NO_MD2
 #error MD2 is disabled.
 #endif
+#include <stddef.h>
 
 #define MD2_DIGEST_LENGTH      16
 #define MD2_BLOCK              16
index 15e77d6..6f68b25 100644 (file)
@@ -63,7 +63,7 @@
 #include <openssl/opensslv.h>
 #include <openssl/crypto.h>
 
-const char *MD2_version="MD2" OPENSSL_VERSION_PTEXT;
+const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT;
 
 /* Implemented from RFC1319 The MD2 Message-Digest Algorithm
  */
index b080cbd..5598c93 100644 (file)
@@ -60,6 +60,7 @@
 #define HEADER_MD4_H
 
 #include <openssl/e_os2.h>
+#include <stddef.h>
 
 #ifdef  __cplusplus
 extern "C" {
index d4c7057..86b79b8 100644 (file)
@@ -60,7 +60,7 @@
 #include "md4_locl.h"
 #include <openssl/opensslv.h>
 
-const char *MD4_version="MD4" OPENSSL_VERSION_PTEXT;
+const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
 
 /* Implemented from RFC1186 The MD4 Message-Digest Algorithm
  */
index 6d283fe..dbdc0e1 100644 (file)
@@ -60,6 +60,7 @@
 #define HEADER_MD5_H
 
 #include <openssl/e_os2.h>
+#include <stddef.h>
 
 #ifdef  __cplusplus
 extern "C" {
index f97f48e..953f049 100644 (file)
@@ -60,7 +60,7 @@
 #include "md5_locl.h"
 #include <openssl/opensslv.h>
 
-const char *MD5_version="MD5" OPENSSL_VERSION_PTEXT;
+const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
 
 /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
  */
index 78439a3..a116bb7 100644 (file)
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 769
-#define NUM_SN 765
-#define NUM_LN 765
-#define NUM_OBJ 721
+#define NUM_NID 772
+#define NUM_SN 768
+#define NUM_LN 768
+#define NUM_OBJ 724
 
-static unsigned char lvalues[5107]={
+static unsigned char lvalues[5116]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -789,6 +789,9 @@ static unsigned char lvalues[5107]={
 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5082] OBJ_camellia_128_ofb128 */
 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5090] OBJ_camellia_192_ofb128 */
 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5098] OBJ_camellia_256_ofb128 */
+0x55,0x1D,0x09,                              /* [5106] OBJ_subject_directory_attributes */
+0x55,0x1D,0x1C,                              /* [5109] OBJ_issuing_distribution_point */
+0x55,0x1D,0x1D,                              /* [5112] OBJ_certificate_issuer */
 };
 
 static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -1987,6 +1990,12 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
        &(lvalues[5090]),0},
 {"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
        &(lvalues[5098]),0},
+{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
+       NID_subject_directory_attributes,3,&(lvalues[5106]),0},
+{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
+       NID_issuing_distribution_point,3,&(lvalues[5109]),0},
+{"certificateIssuer","X509v3 Certificate Issuer",
+       NID_certificate_issuer,3,&(lvalues[5112]),0},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -2203,6 +2212,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[443]),/* "caseIgnoreIA5StringSyntax" */
 &(nid_objs[152]),/* "certBag" */
 &(nid_objs[677]),/* "certicom-arc" */
+&(nid_objs[771]),/* "certificateIssuer" */
 &(nid_objs[89]),/* "certificatePolicies" */
 &(nid_objs[54]),/* "challengePassword" */
 &(nid_objs[407]),/* "characteristic-two-field" */
@@ -2442,6 +2452,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[295]),/* "ipsecTunnel" */
 &(nid_objs[296]),/* "ipsecUser" */
 &(nid_objs[86]),/* "issuerAltName" */
+&(nid_objs[770]),/* "issuingDistributionPoint" */
 &(nid_objs[492]),/* "janetMailbox" */
 &(nid_objs[150]),/* "keyBag" */
 &(nid_objs[83]),/* "keyUsage" */
@@ -2723,6 +2734,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[387]),/* "snmpv2" */
 &(nid_objs[660]),/* "streetAddress" */
 &(nid_objs[85]),/* "subjectAltName" */
+&(nid_objs[769]),/* "subjectDirectoryAttributes" */
 &(nid_objs[398]),/* "subjectInfoAccess" */
 &(nid_objs[82]),/* "subjectKeyIdentifier" */
 &(nid_objs[498]),/* "subtreeMaximumQuality" */
@@ -2852,11 +2864,13 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[103]),/* "X509v3 CRL Distribution Points" */
 &(nid_objs[88]),/* "X509v3 CRL Number" */
 &(nid_objs[141]),/* "X509v3 CRL Reason Code" */
+&(nid_objs[771]),/* "X509v3 Certificate Issuer" */
 &(nid_objs[89]),/* "X509v3 Certificate Policies" */
 &(nid_objs[140]),/* "X509v3 Delta CRL Indicator" */
 &(nid_objs[126]),/* "X509v3 Extended Key Usage" */
 &(nid_objs[748]),/* "X509v3 Inhibit Any Policy" */
 &(nid_objs[86]),/* "X509v3 Issuer Alternative Name" */
+&(nid_objs[770]),/* "X509v3 Issuing Distrubution Point" */
 &(nid_objs[83]),/* "X509v3 Key Usage" */
 &(nid_objs[666]),/* "X509v3 Name Constraints" */
 &(nid_objs[403]),/* "X509v3 No Revocation Available" */
@@ -2864,6 +2878,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[747]),/* "X509v3 Policy Mappings" */
 &(nid_objs[84]),/* "X509v3 Private Key Usage Period" */
 &(nid_objs[85]),/* "X509v3 Subject Alternative Name" */
+&(nid_objs[769]),/* "X509v3 Subject Directory Attributes" */
 &(nid_objs[82]),/* "X509v3 Subject Key Identifier" */
 &(nid_objs[184]),/* "X9.57" */
 &(nid_objs[185]),/* "X9.57 CM ?" */
@@ -3569,6 +3584,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[174]),/* OBJ_dnQualifier                  2 5 4 46 */
 &(nid_objs[510]),/* OBJ_pseudonym                    2 5 4 65 */
 &(nid_objs[400]),/* OBJ_role                         2 5 4 72 */
+&(nid_objs[769]),/* OBJ_subject_directory_attributes 2 5 29 9 */
 &(nid_objs[82]),/* OBJ_subject_key_identifier       2 5 29 14 */
 &(nid_objs[83]),/* OBJ_key_usage                    2 5 29 15 */
 &(nid_objs[84]),/* OBJ_private_key_usage_period     2 5 29 16 */
@@ -3580,6 +3596,8 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[430]),/* OBJ_hold_instruction_code        2 5 29 23 */
 &(nid_objs[142]),/* OBJ_invalidity_date              2 5 29 24 */
 &(nid_objs[140]),/* OBJ_delta_crl                    2 5 29 27 */
+&(nid_objs[770]),/* OBJ_issuing_distribution_point   2 5 29 28 */
+&(nid_objs[771]),/* OBJ_certificate_issuer           2 5 29 29 */
 &(nid_objs[666]),/* OBJ_name_constraints             2 5 29 30 */
 &(nid_objs[103]),/* OBJ_crl_distribution_points      2 5 29 31 */
 &(nid_objs[89]),/* OBJ_certificate_policies         2 5 29 32 */
index 0682979..12b4885 100644 (file)
@@ -91,15 +91,12 @@ static ERR_STRING_DATA OBJ_str_reasons[]=
 
 void ERR_load_OBJ_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,OBJ_str_functs);
                ERR_load_strings(0,OBJ_str_reasons);
-#endif
-
                }
+#endif
        }
index df4ad90..f447bbe 100644 (file)
 #define NID_id_ce              81
 #define OBJ_id_ce              OBJ_X500,29L
 
+#define SN_subject_directory_attributes                "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes                "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes               769
+#define OBJ_subject_directory_attributes               OBJ_id_ce,9L
+
 #define SN_subject_key_identifier              "subjectKeyIdentifier"
 #define LN_subject_key_identifier              "X509v3 Subject Key Identifier"
 #define NID_subject_key_identifier             82
 #define NID_delta_crl          140
 #define OBJ_delta_crl          OBJ_id_ce,27L
 
+#define SN_issuing_distribution_point          "issuingDistributionPoint"
+#define LN_issuing_distribution_point          "X509v3 Issuing Distrubution Point"
+#define NID_issuing_distribution_point         770
+#define OBJ_issuing_distribution_point         OBJ_id_ce,28L
+
+#define SN_certificate_issuer          "certificateIssuer"
+#define LN_certificate_issuer          "X509v3 Certificate Issuer"
+#define NID_certificate_issuer         771
+#define OBJ_certificate_issuer         OBJ_id_ce,29L
+
 #define SN_name_constraints            "nameConstraints"
 #define LN_name_constraints            "X509v3 Name Constraints"
 #define NID_name_constraints           666
index 6a3a360..39b7a1c 100644 (file)
@@ -62,7 +62,7 @@
 ASN1_SEQUENCE(OCSP_SIGNATURE) = {
        ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
        ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
-       ASN1_EXP_SEQUENCE_OF(OCSP_SIGNATURE, certs, X509, 0)
+       ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
 } ASN1_SEQUENCE_END(OCSP_SIGNATURE)
 
 IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
index 2c8ed72..ad62364 100644 (file)
@@ -129,15 +129,12 @@ static ERR_STRING_DATA OCSP_str_reasons[]=
 
 void ERR_load_OCSP_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,OCSP_str_functs);
                ERR_load_strings(0,OCSP_str_reasons);
-#endif
-
                }
+#endif
        }
index 3d58dfb..23ea41c 100644 (file)
@@ -367,7 +367,7 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *st
                return 0;
                }
        gen = req->tbsRequest->requestorName;
-       if (gen->type != GEN_DIRNAME)
+       if (!gen || gen->type != GEN_DIRNAME)
                {
                OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
                return 0;
index beedc19..8a5b34e 100644 (file)
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER 0x0090804f
+#define OPENSSL_VERSION_NUMBER 0x0090805fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8d-fips 28 Sep 2006"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8e-fips 23 Feb 2007"
 #else
-#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8d 28 Sep 2006"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8e 23 Feb 2007"
 #endif
 #define OPENSSL_VERSION_PTEXT  " part of " OPENSSL_VERSION_TEXT
 
index 7db6b42..c28706d 100644 (file)
@@ -221,7 +221,7 @@ typedef struct pem_ctx_st
 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
 return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \
-} \
+} 
 
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x) \
index 7837cde..3133563 100644 (file)
@@ -124,15 +124,12 @@ static ERR_STRING_DATA PEM_str_reasons[]=
 
 void ERR_load_PEM_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(PEM_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,PEM_str_functs);
                ERR_load_strings(0,PEM_str_reasons);
-#endif
-
                }
+#endif
        }
index 7cfc2f3..9bae4c8 100644 (file)
@@ -69,7 +69,7 @@
 #include <openssl/des.h>
 #endif
 
-const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
+const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
 
 #define MIN_LENGTH     4
 
@@ -579,6 +579,7 @@ int PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
                }
        EVP_EncodeFinal(&ctx,buf,&outl);
        if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err;
+       OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
        OPENSSL_free(buf);
        buf = NULL;
        if (    (BIO_write(bp,"-----END ",9) != 9) ||
@@ -587,8 +588,10 @@ int PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
                goto err;
        return(i+outl);
 err:
-       if (buf)
+       if (buf) {
+               OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
                OPENSSL_free(buf);
+       }
        PEMerr(PEM_F_PEM_WRITE_BIO,reason);
        return(0);
        }
index 2162a45..4da4c31 100644 (file)
@@ -125,6 +125,7 @@ p8err:
                PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
 err:
        OPENSSL_free(nm);
+       OPENSSL_cleanse(data, len);
        OPENSSL_free(data);
        return(ret);
        }
index 5c92cb0..07a1fb6 100644 (file)
@@ -133,15 +133,12 @@ static ERR_STRING_DATA PKCS12_str_reasons[]=
 
 void ERR_load_PKCS12_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,PKCS12_str_functs);
                ERR_load_strings(0,PKCS12_str_reasons);
-#endif
-
                }
+#endif
        }
index a4bbba0..a03d7eb 100644 (file)
@@ -217,7 +217,9 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                keylen=EVP_CIPHER_key_length(evp_cipher);
                ivlen=EVP_CIPHER_iv_length(evp_cipher);
                xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
-               if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
+               if (ivlen > 0)
+                       if (RAND_pseudo_bytes(iv,ivlen) <= 0)
+                               goto err;
                if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
                        goto err;
                if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
@@ -226,10 +228,13 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                        goto err;
 
                if (ivlen > 0) {
-                       if (xalg->parameter == NULL) 
-                                               xalg->parameter=ASN1_TYPE_new();
+                       if (xalg->parameter == NULL) {
+                               xalg->parameter = ASN1_TYPE_new();
+                               if (xalg->parameter == NULL)
+                                       goto err;
+                       }
                        if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
-                                                                      goto err;
+                              goto err;
                }
 
                /* Lets do the pub key stuff :-) */
@@ -242,7 +247,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                                PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
                                goto err;
                                }
-                       pkey=X509_get_pubkey(ri->cert);
+                       if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
+                               goto err;
                        jj=EVP_PKEY_size(pkey);
                        EVP_PKEY_free(pkey);
                        if (max < jj) max=jj;
@@ -255,7 +261,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
                        {
                        ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
-                       pkey=X509_get_pubkey(ri->cert);
+                       if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
+                               goto err;
                        jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
                        EVP_PKEY_free(pkey);
                        if (jj <= 0)
@@ -291,6 +298,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                if(bio == NULL)
                        {
                        bio=BIO_new(BIO_s_mem());
+                       if (bio == NULL)
+                               goto err;
                        BIO_set_mem_eof_return(bio,0);
                        }
                }
@@ -541,6 +550,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
                        bio=BIO_new(BIO_s_mem());
                        BIO_set_mem_eof_return(bio,0);
                }
+               if (bio == NULL)
+                       goto err;
 #endif
                }
        BIO_push(out,bio);
@@ -695,9 +706,13 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                                        ERR_R_MALLOC_FAILURE);
                                                goto err;
                                                }
-                                       PKCS7_add_signed_attribute(si,
+                                       if (!PKCS7_add_signed_attribute(si,
                                                NID_pkcs9_signingTime,
-                                               V_ASN1_UTCTIME,sign_time);
+                                               V_ASN1_UTCTIME,sign_time))
+                                               {
+                                               M_ASN1_UTCTIME_free(sign_time);
+                                               goto err;
+                                               }
                                        }
 
                                /* Add digest */
@@ -714,11 +729,16 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                        {
                                        PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
                                                ERR_R_MALLOC_FAILURE);
+                                       M_ASN1_OCTET_STRING_free(digest);
                                        goto err;
                                        }
-                               PKCS7_add_signed_attribute(si,
+                               if (!PKCS7_add_signed_attribute(si,
                                        NID_pkcs9_messageDigest,
-                                       V_ASN1_OCTET_STRING,digest);
+                                       V_ASN1_OCTET_STRING,digest))
+                                       {
+                                       M_ASN1_OCTET_STRING_free(digest);
+                                       goto err;
+                                       }
 
                                /* Now sign the attributes */
                                EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
@@ -976,8 +996,13 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
        int i;
 
        i=OBJ_obj2nid(p7->type);
-       if (i != NID_pkcs7_signedAndEnveloped) return(NULL);
+       if (i != NID_pkcs7_signedAndEnveloped)
+               return NULL;
+       if (p7->d.signed_and_enveloped == NULL)
+               return NULL;
        rsk=p7->d.signed_and_enveloped->recipientinfo;
+       if (rsk == NULL)
+               return NULL;
        ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
        if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
        ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
@@ -1031,6 +1056,8 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
        if (p7si->auth_attr != NULL)
                sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
        p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
+       if (p7si->auth_attr == NULL)
+               return 0;
        for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
                {
                if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
@@ -1049,6 +1076,8 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
                sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
                                           X509_ATTRIBUTE_free);
        p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
+       if (p7si->unauth_attr == NULL)
+               return 0;
        for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
                {
                if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
@@ -1078,10 +1107,16 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
 
        if (*sk == NULL)
                {
-               *sk = sk_X509_ATTRIBUTE_new_null();
+               if (!(*sk = sk_X509_ATTRIBUTE_new_null()))
+                       return 0;
 new_attrib:
-               attr=X509_ATTRIBUTE_create(nid,atrtype,value);
-               sk_X509_ATTRIBUTE_push(*sk,attr);
+               if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
+                       return 0;
+               if (!sk_X509_ATTRIBUTE_push(*sk,attr))
+                       {
+                       X509_ATTRIBUTE_free(attr);
+                       return 0;
+                       }
                }
        else
                {
@@ -1094,7 +1129,13 @@ new_attrib:
                                {
                                X509_ATTRIBUTE_free(attr);
                                attr=X509_ATTRIBUTE_create(nid,atrtype,value);
-                               sk_X509_ATTRIBUTE_set(*sk,i,attr);
+                               if (attr == NULL)
+                                       return 0;
+                               if (!sk_X509_ATTRIBUTE_set(*sk,i,attr))
+                                       {
+                                       X509_ATTRIBUTE_free(attr);
+                                       return 0;
+                                       }
                                goto end;
                                }
                        }
index 58ce679..f249094 100644 (file)
@@ -271,16 +271,23 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
        if (!j) /* we need to add another algorithm */
                {
                if(!(alg=X509_ALGOR_new())
-                       || !(alg->parameter = ASN1_TYPE_new())) {
+                       || !(alg->parameter = ASN1_TYPE_new()))
+                       {
+                       X509_ALGOR_free(alg);
                        PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
                        return(0);
-               }
+                       }
                alg->algorithm=OBJ_nid2obj(nid);
                alg->parameter->type = V_ASN1_NULL;
-               sk_X509_ALGOR_push(md_sk,alg);
+               if (!sk_X509_ALGOR_push(md_sk,alg))
+                       {
+                       X509_ALGOR_free(alg);
+                       return 0;
+                       }
                }
 
-       sk_PKCS7_SIGNER_INFO_push(signer_sk,psi);
+       if (!sk_PKCS7_SIGNER_INFO_push(signer_sk,psi))
+               return 0;
        return(1);
        }
 
@@ -305,8 +312,17 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
 
        if (*sk == NULL)
                *sk=sk_X509_new_null();
+       if (*sk == NULL)
+               {
+               PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+               return 0;
+               }
        CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
-       sk_X509_push(*sk,x509);
+       if (!sk_X509_push(*sk,x509))
+               {
+               X509_free(x509);
+               return 0;
+               }
        return(1);
        }
 
@@ -331,9 +347,18 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
 
        if (*sk == NULL)
                *sk=sk_X509_CRL_new_null();
+       if (*sk == NULL)
+               {
+               PKCS7err(PKCS7_F_PKCS7_ADD_CRL,ERR_R_MALLOC_FAILURE);
+               return 0;
+               }
 
        CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
-       sk_X509_CRL_push(*sk,crl);
+       if (!sk_X509_CRL_push(*sk,crl))
+               {
+               X509_CRL_free(crl);
+               return 0;
+               }
        return(1);
        }
 
@@ -424,6 +449,7 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
        if (!PKCS7_add_signer(p7,si)) goto err;
        return(si);
 err:
+       PKCS7_SIGNER_INFO_free(si);
        return(NULL);
        }
 
@@ -468,6 +494,7 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
        if (!PKCS7_add_recipient_info(p7,ri)) goto err;
        return(ri);
 err:
+       PKCS7_RECIP_INFO_free(ri);
        return(NULL);
        }
 
@@ -490,7 +517,8 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
                return(0);
                }
 
-       sk_PKCS7_RECIP_INFO_push(sk,ri);
+       if (!sk_PKCS7_RECIP_INFO_push(sk,ri))
+               return 0;
        return(1);
        }
 
index dc835e5..fab8513 100644 (file)
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                  BIO *data, int flags)
 {
-       PKCS7 *p7;
+       PKCS7 *p7 = NULL;
        PKCS7_SIGNER_INFO *si;
-       BIO *p7bio;
-       STACK_OF(X509_ALGOR) *smcap;
+       BIO *p7bio = NULL;
+       STACK_OF(X509_ALGOR) *smcap = NULL;
        int i;
 
        if(!X509_check_private_key(signcert, pkey)) {
@@ -82,48 +82,58 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                return NULL;
        }
 
-       PKCS7_set_type(p7, NID_pkcs7_signed);
+       if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+               goto err;
 
-       PKCS7_content_new(p7, NID_pkcs7_data);
+       if (!PKCS7_content_new(p7, NID_pkcs7_data))
+               goto err;
 
-       if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
+       if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
                PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
-               PKCS7_free(p7);
-               return NULL;
+               goto err;
        }
 
        if(!(flags & PKCS7_NOCERTS)) {
-               PKCS7_add_certificate(p7, signcert);
+               if (!PKCS7_add_certificate(p7, signcert))
+                       goto err;
                if(certs) for(i = 0; i < sk_X509_num(certs); i++)
-                       PKCS7_add_certificate(p7, sk_X509_value(certs, i));
+                       if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+                               goto err;
        }
 
        if(!(flags & PKCS7_NOATTR)) {
-               PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
-                               V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
+               if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+                               V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)))
+                       goto err;
                /* Add SMIMECapabilities */
                if(!(flags & PKCS7_NOSMIMECAP))
                {
                if(!(smcap = sk_X509_ALGOR_new_null())) {
                        PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
-                       PKCS7_free(p7);
-                       return NULL;
+                       goto err;
                }
 #ifndef OPENSSL_NO_DES
-               PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1);
+               if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
+                       goto err;
 #endif
 #ifndef OPENSSL_NO_RC2
-               PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128);
-               PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64);
+               if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
+                       goto err;
+               if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
+                       goto err;
 #endif
 #ifndef OPENSSL_NO_DES
-               PKCS7_simple_smimecap (smcap, NID_des_cbc, -1);
+               if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
+                       goto err;
 #endif
 #ifndef OPENSSL_NO_RC2
-               PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40);
+               if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
+                       goto err;
 #endif
-               PKCS7_add_attrib_smimecap (si, smcap);
+               if (!PKCS7_add_attrib_smimecap (si, smcap))
+                       goto err;
                sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+               smcap = NULL;
                }
        }
 
@@ -135,22 +145,24 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 
        if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
                PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
-               PKCS7_free(p7);
-               return NULL;
+               goto err;
        }
 
        SMIME_crlf_copy(data, p7bio, flags);
 
 
-        if (!PKCS7_dataFinal(p7,p7bio)) {
+       if (!PKCS7_dataFinal(p7,p7bio)) {
                PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
-               PKCS7_free(p7);
-               BIO_free_all(p7bio);
-               return NULL;
+               goto err;
        }
 
        BIO_free_all(p7bio);
        return p7;
+err:
+       sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+       BIO_free_all(p7bio);
+       PKCS7_free(p7);
+       return NULL;
 }
 
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
@@ -262,7 +274,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
                tmpin = indata;
                
 
-       p7bio=PKCS7_dataInit(p7,tmpin);
+       if (!(p7bio=PKCS7_dataInit(p7,tmpin)))
+               goto err;
 
        if(flags & PKCS7_TEXT) {
                if(!(tmpout = BIO_new(BIO_s_mem()))) {
@@ -341,7 +354,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
 
        if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
                PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
-               return 0;
+               return NULL;
        }
 
        if(!(signers = sk_X509_new_null())) {
@@ -364,10 +377,13 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
            if (!signer) {
                        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
                        sk_X509_free(signers);
-                       return 0;
+                       return NULL;
            }
 
-           sk_X509_push(signers, signer);
+           if (!sk_X509_push(signers, signer)) {
+                       sk_X509_free(signers);
+                       return NULL;
+           }
        }
        return signers;
 }
@@ -387,7 +403,8 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
                return NULL;
        }
 
-       PKCS7_set_type(p7, NID_pkcs7_enveloped);
+       if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
+               goto err;
        if(!PKCS7_set_cipher(p7, cipher)) {
                PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
                goto err;
@@ -421,7 +438,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
 
        err:
 
-       BIO_free(p7bio);
+       BIO_free_all(p7bio);
        PKCS7_free(p7);
        return NULL;
 
@@ -459,10 +476,13 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
                /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
                if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
                        PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+                       BIO_free_all(tmpmem);
                        return 0;
                }
                if(!(bread = BIO_push(tmpbuf, tmpmem))) {
                        PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+                       BIO_free_all(tmpbuf);
+                       BIO_free_all(tmpmem);
                        return 0;
                }
                ret = SMIME_text(bread, data);
index 4cd2934..c0e3d4c 100644 (file)
@@ -156,15 +156,12 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
 
 void ERR_load_PKCS7_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,PKCS7_str_functs);
                ERR_load_strings(0,PKCS7_str_reasons);
-#endif
-
                }
+#endif
        }
index 6e10f6e..9783d0c 100644 (file)
@@ -152,7 +152,7 @@ static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
 int rand_predictable=0;
 #endif
 
-const char *RAND_version="RAND" OPENSSL_VERSION_PTEXT;
+const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
 
 static void ssleay_rand_cleanup(void);
 static void ssleay_rand_seed(const void *buf, int num);
index b2f2448..386934d 100644 (file)
@@ -85,15 +85,12 @@ static ERR_STRING_DATA RAND_str_reasons[]=
 
 void ERR_load_RAND_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(RAND_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,RAND_str_functs);
                ERR_load_strings(0,RAND_str_reasons);
-#endif
-
                }
+#endif
        }
index d3e8c27..fff86c7 100644 (file)
@@ -60,7 +60,7 @@
 #include "rc2_locl.h"
 #include <openssl/opensslv.h>
 
-const char *RC2_version="RC2" OPENSSL_VERSION_PTEXT;
+const char RC2_version[]="RC2" OPENSSL_VERSION_PTEXT;
 
 /* RC2 as implemented frm a posting from
  * Newsgroups: sci.crypt
index 781ff2d..b22c40b 100644 (file)
@@ -60,7 +60,7 @@
 #include "rc4_locl.h"
 #include <openssl/opensslv.h>
 
-const char *RC4_version="RC4" OPENSSL_VERSION_PTEXT;
+const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT;
 
 const char *RC4_options(void)
        {
index 06bd671..033a596 100644 (file)
@@ -60,6 +60,7 @@
 #define HEADER_RIPEMD_H
 
 #include <openssl/e_os2.h>
+#include <stddef.h>
 
 #ifdef  __cplusplus
 extern "C" {
index 03a286d..9608a8f 100644 (file)
@@ -60,7 +60,7 @@
 #include "rmd_locl.h"
 #include <openssl/opensslv.h>
 
-const char *RMD160_version="RIPE-MD160" OPENSSL_VERSION_PTEXT;
+const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
 
 #  ifdef RMD160_ASM
      void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p,size_t num);
index da7a4fb..fe3ba1b 100644 (file)
@@ -100,7 +100,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23),     "RSA_padding_check_SSLv23"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),       "RSA_padding_check_X931"},
 {ERR_FUNC(RSA_F_RSA_PRINT),    "RSA_print"},
-{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_PRINT_FP"},
+{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
 {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),   "RSA_setup_blinding"},
 {ERR_FUNC(RSA_F_RSA_SIGN),     "RSA_sign"},
 {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),   "RSA_sign_ASN1_OCTET_STRING"},
@@ -160,15 +160,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 
 void ERR_load_RSA_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(RSA_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,RSA_str_functs);
                ERR_load_strings(0,RSA_str_reasons);
-#endif
-
                }
+#endif
        }
index 66cd15f..cca32c0 100644 (file)
@@ -67,7 +67,7 @@
 #include <openssl/engine.h>
 #endif
 
-const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
+const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
 
 static const RSA_METHOD *default_RSA_meth=NULL;
 
index a83bd3c..eed44d7 100644 (file)
@@ -60,6 +60,7 @@
 #define HEADER_SHA_H
 
 #include <openssl/e_os2.h>
+#include <stddef.h>
 
 #ifdef  __cplusplus
 extern "C" {
index 447ce53..50d1925 100644 (file)
@@ -64,7 +64,7 @@
 
 #include <openssl/opensslv.h>
 
-const char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT;
+const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT;
 
 /* The implementation is in ../md32_common.h */
 
index bbc20da..05ae944 100644 (file)
@@ -14,7 +14,7 @@
 #include <openssl/sha.h>
 #include <openssl/opensslv.h>
 
-const char *SHA256_version="SHA-256" OPENSSL_VERSION_PTEXT;
+const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
 
 int SHA224_Init (SHA256_CTX *c)
        {
index f965cff..39d18b8 100644 (file)
@@ -50,7 +50,7 @@
 
 #include "cryptlib.h"
 
-const char *SHA512_version="SHA-512" OPENSSL_VERSION_PTEXT;
+const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
 
 #if defined(_M_IX86) || defined(_M_AMD64) || defined(__i386) || defined(__x86_64)
 #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
index 60465d0..70eb560 100644 (file)
@@ -64,7 +64,7 @@
 
 #include <openssl/opensslv.h>
 
-const char *SHA_version="SHA" OPENSSL_VERSION_PTEXT;
+const char SHA_version[]="SHA" OPENSSL_VERSION_PTEXT;
 
 /* The implementation is in ../md32_common.h */
 
index e5f5be9..d496f36 100644 (file)
@@ -234,6 +234,28 @@ STACK_OF(type) \
 #define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
 #define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
 
+#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st))
+#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+
 #define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
 #define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
 #define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
@@ -608,6 +630,50 @@ STACK_OF(type) \
 #define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
 #define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
 
+#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st))
+#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+
+#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+
 #define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
 #define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
 #define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
index 5967a2c..378bd7c 100644 (file)
@@ -73,7 +73,7 @@
 #undef MIN_NODES
 #define MIN_NODES      4
 
-const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
+const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT;
 
 #include <errno.h>
 
index 5c6fe83..6fee649 100644 (file)
@@ -200,15 +200,12 @@ static ERR_STRING_DATA STORE_str_reasons[]=
 
 void ERR_load_STORE_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(STORE_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,STORE_str_functs);
                ERR_load_strings(0,STORE_str_reasons);
-#endif
-
                }
+#endif
        }
index e9e503e..3ed5f72 100644 (file)
@@ -66,7 +66,7 @@
 #undef BUFSIZE
 #define BUFSIZE        512
 
-const char *TXT_DB_version="TXT_DB" OPENSSL_VERSION_PTEXT;
+const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
 
 TXT_DB *TXT_DB_read(BIO *in, int num)
        {
index d983cdd..786bd0d 100644 (file)
@@ -101,15 +101,12 @@ static ERR_STRING_DATA UI_str_reasons[]=
 
 void ERR_load_UI_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(UI_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,UI_str_functs);
                ERR_load_strings(0,UI_str_reasons);
-#endif
-
                }
+#endif
        }
index ea689ae..37f9a48 100644 (file)
@@ -189,7 +189,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
 
        s=dir;
        p=s;
-       for (;;)
+       for (;;p++)
                {
                if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
                        {
@@ -198,8 +198,11 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
                        len=(int)(p-ss);
                        if (len == 0) continue;
                        for (j=0; j<ctx->num_dirs; j++)
-                               if (strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0)
-                                       continue;
+                               if (strlen(ctx->dirs[j]) == (size_t)len &&
+                                   strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0)
+                                       break;
+                       if (j<ctx->num_dirs)
+                               continue;
                        if (ctx->num_dirs_alloced < (ctx->num_dirs+1))
                                {
                                ctx->num_dirs_alloced+=10;
@@ -231,7 +234,6 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
                        ctx->num_dirs++;
                        }
                if (*p == '\0') break;
-               p++;
                }
        return(1);
        }
index 66990ae..16a954f 100644 (file)
@@ -288,6 +288,10 @@ struct x509_st
        ASN1_OCTET_STRING *skid;
        struct AUTHORITY_KEYID_st *akid;
        X509_POLICY_CACHE *policy_cache;
+#ifndef OPENSSL_NO_RFC3779
+       STACK_OF(IPAddressFamily) *rfc3779_addr;
+       struct ASIdentifiers_st *rfc3779_asid;
+#endif
 #ifndef OPENSSL_NO_SHA
        unsigned char sha1_hash[SHA_DIGEST_LENGTH];
 #endif
index b7bc383..fb37729 100644 (file)
@@ -150,15 +150,12 @@ static ERR_STRING_DATA X509_str_reasons[]=
 
 void ERR_load_X509_strings(void)
        {
-       static int init=1;
+#ifndef OPENSSL_NO_ERR
 
-       if (init)
+       if (ERR_func_error_string(X509_str_functs[0].error) == NULL)
                {
-               init=0;
-#ifndef OPENSSL_NO_ERR
                ERR_load_strings(0,X509_str_functs);
                ERR_load_strings(0,X509_str_reasons);
-#endif
-
                }
+#endif
        }
index ab13bcf..3872e1f 100644 (file)
@@ -242,6 +242,11 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
        at = NULL;
        attr->single = 0;
        attr->object = OBJ_nid2obj(nid);
+       if (!req->req_info->attributes)
+               {
+               if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
+                       goto err;
+               }
        if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
        return 1;
        err:
index 7dd2b76..a80c87e 100644 (file)
@@ -162,6 +162,8 @@ const char *X509_verify_cert_error_string(long n)
                return("invalid or inconsistent certificate policy extension");
        case X509_V_ERR_NO_EXPLICIT_POLICY:
                return("no explicit policy");
+       case X509_V_ERR_UNNESTED_RESOURCE:
+               return("RFC 3779 resource not subset of parent's resources");
        default:
                BIO_snprintf(buf,sizeof buf,"error number %ld",n);
                return(buf);
index 79dae3d..07df21f 100644 (file)
@@ -79,7 +79,7 @@ static int check_revocation(X509_STORE_CTX *ctx);
 static int check_cert(X509_STORE_CTX *ctx);
 static int check_policy(X509_STORE_CTX *ctx);
 static int internal_verify(X509_STORE_CTX *ctx);
-const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
+const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
 
 
 static int null_callback(int ok, X509_STORE_CTX *e)
@@ -312,6 +312,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
                ok=internal_verify(ctx);
        if(!ok) goto end;
 
+#ifndef OPENSSL_NO_RFC3779
+       /* RFC 3779 path validation, now that CRL check has been done */
+       ok = v3_asid_validate_path(ctx);
+       if (!ok) goto end;
+       ok = v3_addr_validate_path(ctx);
+       if (!ok) goto end;
+#endif
+
        /* If we get this far evaluate policies */
        if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
                ok = ctx->check_policy(ctx);
@@ -1460,9 +1468,16 @@ void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
        {
        if (ctx->cleanup) ctx->cleanup(ctx);
-       X509_VERIFY_PARAM_free(ctx->param);
-       if (ctx->tree)
+       if (ctx->param != NULL)
+               {
+               X509_VERIFY_PARAM_free(ctx->param);
+               ctx->param=NULL;
+               }
+       if (ctx->tree != NULL)
+               {
                X509_policy_tree_free(ctx->tree);
+               ctx->tree=NULL;
+               }
        if (ctx->chain != NULL)
                {
                sk_X509_pop_free(ctx->chain,X509_free);
index 3f16330..76c76e1 100644 (file)
@@ -331,6 +331,7 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 #define                X509_V_ERR_INVALID_POLICY_EXTENSION             42
 #define                X509_V_ERR_NO_EXPLICIT_POLICY                   43
 
+#define                X509_V_ERR_UNNESTED_RESOURCE                    44
 
 /* The application is not happy */
 #define                X509_V_ERR_APPLICATION_VERIFICATION             50
index 3596684..5c063ac 100644 (file)
@@ -67,6 +67,9 @@ extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
 extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
 extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
 extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp;
+#ifndef OPENSSL_NO_RFC3779
+extern X509V3_EXT_METHOD v3_addr, v3_asid;
+#endif
 
 /* This table will be searched using OBJ_bsearch so it *must* kept in
  * order of the ext_nid values.
@@ -99,6 +102,10 @@ static X509V3_EXT_METHOD *standard_exts[] = {
 #endif
 &v3_sxnet,
 &v3_info,
+#ifndef OPENSSL_NO_RFC3779
+&v3_addr,
+&v3_asid,
+#endif
 #ifndef OPENSSL_NO_OCSP
 &v3_ocsp_nonce,
 &v3_ocsp_crlid,
index 1c68ce3..27d29f2 100644 (file)
@@ -197,7 +197,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                        /* Any matching allowed if certificate is self
                         * issued and not the last in the chain.
                         */
-                       if (!(x->ex_flags && EXFLAG_SS) || (i == 0))
+                       if (!(x->ex_flags & EXFLAG_SS) || (i == 0))
                                level->flags |= X509_V_FLAG_INHIBIT_ANY;
                        }
                else
@@ -628,6 +628,16 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
                /* Tree OK: continue */
 
                case 1:
+               if (!tree)
+                       /*
+                        * tree_init() returns success and a null tree
+                        * if it's just looking at a trust anchor.
+                        * I'm not sure that returning success here is
+                        * correct, but I'm sure that reporting this
+                        * as an internal error which our caller
+                        * interprets as a malloc failure is wrong.
+                        */
+                       return 1;
                break;
                }
 
diff --git a/crypto/openssl-0.9/crypto/x509v3/v3_addr.c b/crypto/openssl-0.9/crypto/x509v3/v3_addr.c
new file mode 100644 (file)
index 0000000..ed9847b
--- /dev/null
@@ -0,0 +1,1280 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 2.2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/buffer.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
+ */
+
+ASN1_SEQUENCE(IPAddressRange) = {
+  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(IPAddressRange)
+
+ASN1_CHOICE(IPAddressOrRange) = {
+  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
+} ASN1_CHOICE_END(IPAddressOrRange)
+
+ASN1_CHOICE(IPAddressChoice) = {
+  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
+  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
+} ASN1_CHOICE_END(IPAddressChoice)
+
+ASN1_SEQUENCE(IPAddressFamily) = {
+  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
+  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
+} ASN1_SEQUENCE_END(IPAddressFamily)
+
+ASN1_ITEM_TEMPLATE(IPAddrBlocks) = 
+  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
+                       IPAddrBlocks, IPAddressFamily)
+ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
+
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * How much buffer space do we need for a raw address?
+ */
+#define ADDR_RAW_BUF_LEN       16
+
+/*
+ * What's the address length associated with this AFI?
+ */
+static int length_from_afi(const unsigned afi)
+{
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    return 4;
+  case IANA_AFI_IPV6:
+    return 16;
+  default:
+    return 0;
+  }
+}
+
+/*
+ * Extract the AFI from an IPAddressFamily.
+ */
+unsigned v3_addr_get_afi(const IPAddressFamily *f)
+{
+  return ((f != NULL &&
+          f->addressFamily != NULL &&
+          f->addressFamily->data != NULL)
+         ? ((f->addressFamily->data[0] << 8) |
+            (f->addressFamily->data[1]))
+         : 0);
+}
+
+/*
+ * Expand the bitstring form of an address into a raw byte array.
+ * At the moment this is coded for simplicity, not speed.
+ */
+static void addr_expand(unsigned char *addr,
+                       const ASN1_BIT_STRING *bs,
+                       const int length,
+                       const unsigned char fill)
+{
+  assert(bs->length >= 0 && bs->length <= length);
+  if (bs->length > 0) {
+    memcpy(addr, bs->data, bs->length);
+    if ((bs->flags & 7) != 0) {
+      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
+      if (fill == 0)
+       addr[bs->length - 1] &= ~mask;
+      else
+       addr[bs->length - 1] |= mask;
+    }
+  }
+  memset(addr + bs->length, fill, length - bs->length);
+}
+
+/*
+ * Extract the prefix length from a bitstring.
+ */
+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
+
+/*
+ * i2r handler for one address bitstring.
+ */
+static int i2r_address(BIO *out,
+                      const unsigned afi,
+                      const unsigned char fill,
+                      const ASN1_BIT_STRING *bs)
+{
+  unsigned char addr[ADDR_RAW_BUF_LEN];
+  int i, n;
+
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    addr_expand(addr, bs, 4, fill);
+    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+    break;
+  case IANA_AFI_IPV6:
+    addr_expand(addr, bs, 16, fill);
+    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
+      ;
+    for (i = 0; i < n; i += 2)
+      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
+    if (i < 16)
+      BIO_puts(out, ":");
+    break;
+  default:
+    for (i = 0; i < bs->length; i++)
+      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
+    BIO_printf(out, "[%d]", (int) (bs->flags & 7));
+    break;
+  }
+  return 1;
+}
+
+/*
+ * i2r handler for a sequence of addresses and ranges.
+ */
+static int i2r_IPAddressOrRanges(BIO *out,
+                                const int indent,
+                                const IPAddressOrRanges *aors,
+                                const unsigned afi)
+{
+  int i;
+  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
+    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
+    BIO_printf(out, "%*s", indent, "");
+    switch (aor->type) {
+    case IPAddressOrRange_addressPrefix:
+      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
+       return 0;
+      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
+      continue;
+    case IPAddressOrRange_addressRange:
+      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
+       return 0;
+      BIO_puts(out, "-");
+      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
+       return 0;
+      BIO_puts(out, "\n");
+      continue;
+    }
+  }
+  return 1;
+}
+
+/*
+ * i2r handler for an IPAddrBlocks extension.
+ */
+static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
+                           void *ext,
+                           BIO *out,
+                           int indent)
+{
+  const IPAddrBlocks *addr = ext;
+  int i;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    const unsigned afi = v3_addr_get_afi(f);
+    switch (afi) {
+    case IANA_AFI_IPV4:
+      BIO_printf(out, "%*sIPv4", indent, "");
+      break;
+    case IANA_AFI_IPV6:
+      BIO_printf(out, "%*sIPv6", indent, "");
+      break;
+    default:
+      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
+      break;
+    }
+    if (f->addressFamily->length > 2) {
+      switch (f->addressFamily->data[2]) {
+      case   1:
+       BIO_puts(out, " (Unicast)");
+       break;
+      case   2:
+       BIO_puts(out, " (Multicast)");
+       break;
+      case   3:
+       BIO_puts(out, " (Unicast/Multicast)");
+       break;
+      case   4:
+       BIO_puts(out, " (MPLS)");
+       break;
+      case  64:
+       BIO_puts(out, " (Tunnel)");
+       break;
+      case  65:
+       BIO_puts(out, " (VPLS)");
+       break;
+      case  66:
+       BIO_puts(out, " (BGP MDT)");
+       break;
+      case 128:
+       BIO_puts(out, " (MPLS-labeled VPN)");
+       break;
+      default:  
+       BIO_printf(out, " (Unknown SAFI %u)",
+                  (unsigned) f->addressFamily->data[2]);
+       break;
+      }
+    }
+    switch (f->ipAddressChoice->type) {
+    case IPAddressChoice_inherit:
+      BIO_puts(out, ": inherit\n");
+      break;
+    case IPAddressChoice_addressesOrRanges:
+      BIO_puts(out, ":\n");
+      if (!i2r_IPAddressOrRanges(out,
+                                indent + 2,
+                                f->ipAddressChoice->u.addressesOrRanges,
+                                afi))
+       return 0;
+      break;
+    }
+  }
+  return 1;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressOrRange
+ * elements.
+ */
+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
+                               const IPAddressOrRange *b,
+                               const int length)
+{
+  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
+  int prefixlen_a = 0;
+  int prefixlen_b = 0;
+  int r;
+
+  switch (a->type) {
+  case IPAddressOrRange_addressPrefix:
+    addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
+    prefixlen_a = addr_prefixlen(a->u.addressPrefix);
+    break;
+  case IPAddressOrRange_addressRange:
+    addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
+    prefixlen_a = length * 8;
+    break;
+  }
+
+  switch (b->type) {
+  case IPAddressOrRange_addressPrefix:
+    addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
+    prefixlen_b = addr_prefixlen(b->u.addressPrefix);
+    break;
+  case IPAddressOrRange_addressRange:
+    addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
+    prefixlen_b = length * 8;
+    break;
+  }
+
+  if ((r = memcmp(addr_a, addr_b, length)) != 0)
+    return r;
+  else
+    return prefixlen_a - prefixlen_b;
+}
+
+/*
+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+                                 const IPAddressOrRange * const *b)
+{
+  return IPAddressOrRange_cmp(*a, *b, 4);
+}
+
+/*
+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+                                 const IPAddressOrRange * const *b)
+{
+  return IPAddressOrRange_cmp(*a, *b, 16);
+}
+
+/*
+ * Calculate whether a range collapses to a prefix.
+ * See last paragraph of RFC 3779 2.2.3.7.
+ */
+static int range_should_be_prefix(const unsigned char *min,
+                                 const unsigned char *max,
+                                 const int length)
+{
+  unsigned char mask;
+  int i, j;
+
+  for (i = 0; i < length && min[i] == max[i]; i++)
+    ;
+  for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
+    ;
+  if (i < j)
+    return -1;
+  if (i > j)
+    return i * 8;
+  mask = min[i] ^ max[i];
+  switch (mask) {
+  case 0x01: j = 7; break;
+  case 0x03: j = 6; break;
+  case 0x07: j = 5; break;
+  case 0x0F: j = 4; break;
+  case 0x1F: j = 3; break;
+  case 0x3F: j = 2; break;
+  case 0x7F: j = 1; break;
+  default:   return -1;
+  }
+  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
+    return -1;
+  else
+    return i * 8 + j;
+}
+
+/*
+ * Construct a prefix.
+ */
+static int make_addressPrefix(IPAddressOrRange **result,
+                             unsigned char *addr,
+                             const int prefixlen)
+{
+  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
+  IPAddressOrRange *aor = IPAddressOrRange_new();
+
+  if (aor == NULL)
+    return 0;
+  aor->type = IPAddressOrRange_addressPrefix;
+  if (aor->u.addressPrefix == NULL &&
+      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
+    goto err;
+  aor->u.addressPrefix->flags &= ~7;
+  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (bitlen > 0) {
+    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
+    aor->u.addressPrefix->flags |= 8 - bitlen;
+  }
+  
+  *result = aor;
+  return 1;
+
+ err:
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Construct a range.  If it can be expressed as a prefix,
+ * return a prefix instead.  Doing this here simplifies
+ * the rest of the code considerably.
+ */
+static int make_addressRange(IPAddressOrRange **result,
+                            unsigned char *min,
+                            unsigned char *max,
+                            const int length)
+{
+  IPAddressOrRange *aor;
+  int i, prefixlen;
+
+  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
+    return make_addressPrefix(result, min, prefixlen);
+
+  if ((aor = IPAddressOrRange_new()) == NULL)
+    return 0;
+  aor->type = IPAddressOrRange_addressRange;
+  assert(aor->u.addressRange == NULL);
+  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
+    goto err;
+  if (aor->u.addressRange->min == NULL &&
+      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+  if (aor->u.addressRange->max == NULL &&
+      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
+    goto err;
+
+  for (i = length; i > 0 && min[i - 1] == 0x00; --i)
+    ;
+  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
+    goto err;
+  aor->u.addressRange->min->flags &= ~7;
+  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (i > 0) {
+    unsigned char b = min[i - 1];
+    int j = 1;
+    while ((b & (0xFFU >> j)) != 0) 
+      ++j;
+    aor->u.addressRange->min->flags |= 8 - j;
+  }
+
+  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
+    ;
+  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
+    goto err;
+  aor->u.addressRange->max->flags &= ~7;
+  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+  if (i > 0) {
+    unsigned char b = max[i - 1];
+    int j = 1;
+    while ((b & (0xFFU >> j)) != (0xFFU >> j))
+      ++j;
+    aor->u.addressRange->max->flags |= 8 - j;
+  }
+
+  *result = aor;
+  return 1;
+
+ err:
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Construct a new address family or find an existing one.
+ */
+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
+                                            const unsigned afi,
+                                            const unsigned *safi)
+{
+  IPAddressFamily *f;
+  unsigned char key[3];
+  unsigned keylen;
+  int i;
+
+  key[0] = (afi >> 8) & 0xFF;
+  key[1] = afi & 0xFF;
+  if (safi != NULL) {
+    key[2] = *safi & 0xFF;
+    keylen = 3;
+  } else {
+    keylen = 2;
+  }
+
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    f = sk_IPAddressFamily_value(addr, i);
+    assert(f->addressFamily->data != NULL);
+    if (f->addressFamily->length == keylen &&
+       !memcmp(f->addressFamily->data, key, keylen))
+      return f;
+  }
+
+  if ((f = IPAddressFamily_new()) == NULL)
+    goto err;
+  if (f->ipAddressChoice == NULL &&
+      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
+    goto err;
+  if (f->addressFamily == NULL && 
+      (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
+    goto err;
+  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
+    goto err;
+  if (!sk_IPAddressFamily_push(addr, f))
+    goto err;
+
+  return f;
+
+ err:
+  IPAddressFamily_free(f);
+  return NULL;
+}
+
+/*
+ * Add an inheritance element.
+ */
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+                       const unsigned afi,
+                       const unsigned *safi)
+{
+  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+  if (f == NULL ||
+      f->ipAddressChoice == NULL ||
+      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+       f->ipAddressChoice->u.addressesOrRanges != NULL))
+    return 0;
+  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+      f->ipAddressChoice->u.inherit != NULL)
+    return 1;
+  if (f->ipAddressChoice->u.inherit == NULL &&
+      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
+    return 0;
+  f->ipAddressChoice->type = IPAddressChoice_inherit;
+  return 1;
+}
+
+/*
+ * Construct an IPAddressOrRange sequence, or return an existing one.
+ */
+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
+                                              const unsigned afi,
+                                              const unsigned *safi)
+{
+  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+  IPAddressOrRanges *aors = NULL;
+
+  if (f == NULL ||
+      f->ipAddressChoice == NULL ||
+      (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+       f->ipAddressChoice->u.inherit != NULL))
+    return NULL;
+  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
+    aors = f->ipAddressChoice->u.addressesOrRanges;
+  if (aors != NULL)
+    return aors;
+  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
+    return NULL;
+  switch (afi) {
+  case IANA_AFI_IPV4:
+    sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+    break;
+  case IANA_AFI_IPV6:
+    sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+    break;
+  }
+  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
+  f->ipAddressChoice->u.addressesOrRanges = aors;
+  return aors;
+}
+
+/*
+ * Add a prefix.
+ */
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+                      const unsigned afi,
+                      const unsigned *safi,
+                      unsigned char *a,
+                      const int prefixlen)
+{
+  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+  IPAddressOrRange *aor;
+  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+    return 0;
+  if (sk_IPAddressOrRange_push(aors, aor))
+    return 1;
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Add a range.
+ */
+int v3_addr_add_range(IPAddrBlocks *addr,
+                     const unsigned afi,
+                     const unsigned *safi,
+                     unsigned char *min,
+                     unsigned char *max)
+{
+  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+  IPAddressOrRange *aor;
+  int length = length_from_afi(afi);
+  if (aors == NULL)
+    return 0;
+  if (!make_addressRange(&aor, min, max, length))
+    return 0;
+  if (sk_IPAddressOrRange_push(aors, aor))
+    return 1;
+  IPAddressOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Extract min and max values from an IPAddressOrRange.
+ */
+static void extract_min_max(IPAddressOrRange *aor,
+                           unsigned char *min,
+                           unsigned char *max,
+                           int length)
+{
+  assert(aor != NULL && min != NULL && max != NULL);
+  switch (aor->type) {
+  case IPAddressOrRange_addressPrefix:
+    addr_expand(min, aor->u.addressPrefix, length, 0x00);
+    addr_expand(max, aor->u.addressPrefix, length, 0xFF);
+    return;
+  case IPAddressOrRange_addressRange:
+    addr_expand(min, aor->u.addressRange->min, length, 0x00);
+    addr_expand(max, aor->u.addressRange->max, length, 0xFF);
+    return;
+  }
+}
+
+/*
+ * Public wrapper for extract_min_max().
+ */
+int v3_addr_get_range(IPAddressOrRange *aor,
+                     const unsigned afi,
+                     unsigned char *min,
+                     unsigned char *max,
+                     const int length)
+{
+  int afi_length = length_from_afi(afi);
+  if (aor == NULL || min == NULL || max == NULL ||
+      afi_length == 0 || length < afi_length ||
+      (aor->type != IPAddressOrRange_addressPrefix &&
+       aor->type != IPAddressOrRange_addressRange))
+    return 0;
+  extract_min_max(aor, min, max, afi_length);
+  return afi_length;
+}
+
+/*
+ * Sort comparision function for a sequence of IPAddressFamily.
+ *
+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
+ * the ordering: I can read it as meaning that IPv6 without a SAFI
+ * comes before IPv4 with a SAFI, which seems pretty weird.  The
+ * examples in appendix B suggest that the author intended the
+ * null-SAFI rule to apply only within a single AFI, which is what I
+ * would have expected and is what the following code implements.
+ */
+static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
+                              const IPAddressFamily * const *b_)
+{
+  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
+  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
+  int len = ((a->length <= b->length) ? a->length : b->length);
+  int cmp = memcmp(a->data, b->data, len);
+  return cmp ? cmp : a->length - b->length;
+}
+
+/*
+ * Check whether an IPAddrBLocks is in canonical form.
+ */
+int v3_addr_is_canonical(IPAddrBlocks *addr)
+{
+  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+  IPAddressOrRanges *aors;
+  int i, j, k;
+
+  /*
+   * Empty extension is cannonical.
+   */
+  if (addr == NULL)
+    return 1;
+
+  /*
+   * Check whether the top-level list is in order.
+   */
+  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
+    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
+    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
+    if (IPAddressFamily_cmp(&a, &b) >= 0)
+      return 0;
+  }
+
+  /*
+   * Top level's ok, now check each address family.
+   */
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    int length = length_from_afi(v3_addr_get_afi(f));
+
+    /*
+     * Inheritance is canonical.  Anything other than inheritance or
+     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
+     */
+    if (f == NULL || f->ipAddressChoice == NULL)
+      return 0;
+    switch (f->ipAddressChoice->type) {
+    case IPAddressChoice_inherit:
+      continue;
+    case IPAddressChoice_addressesOrRanges:
+      break;
+    default:
+      return 0;
+    }
+
+    /*
+     * It's an IPAddressOrRanges sequence, check it.
+     */
+    aors = f->ipAddressChoice->u.addressesOrRanges;
+    if (sk_IPAddressOrRange_num(aors) == 0)
+      return 0;
+    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
+      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
+
+      extract_min_max(a, a_min, a_max, length);
+      extract_min_max(b, b_min, b_max, length);
+
+      /*
+       * Punt misordered list, overlapping start, or inverted range.
+       */
+      if (memcmp(a_min, b_min, length) >= 0 ||
+         memcmp(a_min, a_max, length) > 0 ||
+         memcmp(b_min, b_max, length) > 0)
+       return 0;
+
+      /*
+       * Punt if adjacent or overlapping.  Check for adjacency by
+       * subtracting one from b_min first.
+       */
+      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
+       ;
+      if (memcmp(a_max, b_min, length) >= 0)
+       return 0;
+
+      /*
+       * Check for range that should be expressed as a prefix.
+       */
+      if (a->type == IPAddressOrRange_addressRange &&
+         range_should_be_prefix(a_min, a_max, length) >= 0)
+       return 0;
+    }
+
+    /*
+     * Check final range to see if it should be a prefix.
+     */
+    j = sk_IPAddressOrRange_num(aors) - 1;
+    {
+      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+      if (a->type == IPAddressOrRange_addressRange) {
+       extract_min_max(a, a_min, a_max, length);
+       if (range_should_be_prefix(a_min, a_max, length) >= 0)
+         return 0;
+      }
+    }
+  }
+
+  /*
+   * If we made it through all that, we're happy.
+   */
+  return 1;
+}
+
+/*
+ * Whack an IPAddressOrRanges into canonical form.
+ */
+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
+                                     const unsigned afi)
+{
+  int i, j, length = length_from_afi(afi);
+
+  /*
+   * Sort the IPAddressOrRanges sequence.
+   */
+  sk_IPAddressOrRange_sort(aors);
+
+  /*
+   * Clean up representation issues, punt on duplicates or overlaps.
+   */
+  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
+    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
+    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+
+    extract_min_max(a, a_min, a_max, length);
+    extract_min_max(b, b_min, b_max, length);
+
+    /*
+     * Punt overlaps.
+     */
+    if (memcmp(a_max, b_min, length) >= 0)
+      return 0;
+
+    /*
+     * Merge if a and b are adjacent.  We check for
+     * adjacency by subtracting one from b_min first.
+     */
+    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
+      ;
+    if (memcmp(a_max, b_min, length) == 0) {
+      IPAddressOrRange *merged;
+      if (!make_addressRange(&merged, a_min, b_max, length))
+       return 0;
+      sk_IPAddressOrRange_set(aors, i, merged);
+      sk_IPAddressOrRange_delete(aors, i + 1);
+      IPAddressOrRange_free(a);
+      IPAddressOrRange_free(b);
+      --i;
+      continue;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Whack an IPAddrBlocks extension into canonical form.
+ */
+int v3_addr_canonize(IPAddrBlocks *addr)
+{
+  int i;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+       !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
+                                   v3_addr_get_afi(f)))
+      return 0;
+  }
+  sk_IPAddressFamily_sort(addr);
+  assert(v3_addr_is_canonical(addr));
+  return 1;
+}
+
+/*
+ * v2i handler for the IPAddrBlocks extension.
+ */
+static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
+                             struct v3_ext_ctx *ctx,
+                             STACK_OF(CONF_VALUE) *values)
+{
+  static const char v4addr_chars[] = "0123456789.";
+  static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
+  IPAddrBlocks *addr = NULL;
+  char *s = NULL, *t;
+  int i;
+  
+  if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
+    X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+
+  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+    unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
+    unsigned afi, *safi = NULL, safi_;
+    const char *addr_chars;
+    int prefixlen, i1, i2, delim, length;
+
+    if (       !name_cmp(val->name, "IPv4")) {
+      afi = IANA_AFI_IPV4;
+    } else if (!name_cmp(val->name, "IPv6")) {
+      afi = IANA_AFI_IPV6;
+    } else if (!name_cmp(val->name, "IPv4-SAFI")) {
+      afi = IANA_AFI_IPV4;
+      safi = &safi_;
+    } else if (!name_cmp(val->name, "IPv6-SAFI")) {
+      afi = IANA_AFI_IPV6;
+      safi = &safi_;
+    } else {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    switch (afi) {
+    case IANA_AFI_IPV4:
+      addr_chars = v4addr_chars;
+      break;
+    case IANA_AFI_IPV6:
+      addr_chars = v6addr_chars;
+      break;
+    }
+
+    length = length_from_afi(afi);
+
+    /*
+     * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
+     * the other input values.
+     */
+    if (safi != NULL) {
+      *safi = strtoul(val->value, &t, 0);
+      t += strspn(t, " \t");
+      if (*safi > 0xFF || *t++ != ':') {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      t += strspn(t, " \t");
+      s = BUF_strdup(t);
+    } else {
+      s = BUF_strdup(val->value);
+    }
+    if (s == NULL) {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+
+    /*
+     * Check for inheritance.  Not worth additional complexity to
+     * optimize this (seldom-used) case.
+     */
+    if (!strcmp(s, "inherit")) {
+      if (!v3_addr_add_inherit(addr, afi, safi)) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      OPENSSL_free(s);
+      s = NULL;
+      continue;
+    }
+
+    i1 = strspn(s, addr_chars);
+    i2 = i1 + strspn(s + i1, " \t");
+    delim = s[i2++];
+    s[i1] = '\0';
+
+    if (a2i_ipadd(min, s) != length) {
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    switch (delim) {
+    case '/':
+      prefixlen = (int) strtoul(s + i2, &t, 10);
+      if (t == s + i2 || *t != '\0') {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+      break;
+    case '-':
+      i1 = i2 + strspn(s + i2, " \t");
+      i2 = i1 + strspn(s + i1, addr_chars);
+      if (i1 == i2 || s[i2] != '\0') {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      if (a2i_ipadd(max, s + i1) != length) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      if (!v3_addr_add_range(addr, afi, safi, min, max)) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+      break;
+    case '\0':
+      if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+      break;
+    default:
+      X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    OPENSSL_free(s);
+    s = NULL;
+  }
+
+  /*
+   * Canonize the result, then we're done.
+   */
+  if (!v3_addr_canonize(addr))
+    goto err;    
+  return addr;
+
+ err:
+  OPENSSL_free(s);
+  sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+  return NULL;
+}
+
+/*
+ * OpenSSL dispatch
+ */
+const X509V3_EXT_METHOD v3_addr = {
+  NID_sbgp_ipAddrBlock,                /* nid */
+  0,                           /* flags */
+  ASN1_ITEM_ref(IPAddrBlocks), /* template */
+  0, 0, 0, 0,                  /* old functions, ignored */
+  0,                           /* i2s */
+  0,                           /* s2i */
+  0,                           /* i2v */
+  v2i_IPAddrBlocks,            /* v2i */
+  i2r_IPAddrBlocks,            /* i2r */
+  0,                           /* r2i */
+  NULL                         /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension sues inheritance.
+ */
+int v3_addr_inherits(IPAddrBlocks *addr)
+{
+  int i;
+  if (addr == NULL)
+    return 0;
+  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+    if (f->ipAddressChoice->type == IPAddressChoice_inherit)
+      return 1;
+  }
+  return 0;
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int addr_contains(IPAddressOrRanges *parent,
+                        IPAddressOrRanges *child,
+                        int length)
+{
+  unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
+  unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
+  int p, c;
+
+  if (child == NULL || parent == child)
+    return 1;
+  if (parent == NULL)
+    return 0;
+
+  p = 0;
+  for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
+    extract_min_max(sk_IPAddressOrRange_value(child, c),
+                   c_min, c_max, length);
+    for (;; p++) {
+      if (p >= sk_IPAddressOrRange_num(parent))
+       return 0;
+      extract_min_max(sk_IPAddressOrRange_value(parent, p),
+                     p_min, p_max, length);
+      if (memcmp(p_max, c_max, length) < 0)
+       continue;
+      if (memcmp(p_min, c_min, length) > 0)
+       return 0;
+      break;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
+{
+  int i;
+  if (a == NULL || a == b)
+    return 1;
+  if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
+    return 0;
+  sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+  for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
+    IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
+    int j = sk_IPAddressFamily_find(b, fa);
+    IPAddressFamily *fb = sk_IPAddressFamily_value(b, j);
+    if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
+                      fa->ipAddressChoice->u.addressesOrRanges,
+                      length_from_afi(v3_addr_get_afi(fb))))
+      return 0;
+  }
+  return 1;
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)          \
+  do {                                 \
+    if (ctx != NULL) {                 \
+      ctx->error = _err_;              \
+      ctx->error_depth = i;            \
+      ctx->current_cert = x;           \
+      ret = ctx->verify_cb(0, ctx);    \
+    } else {                           \
+      ret = 0;                         \
+    }                                  \
+    if (!ret)                          \
+      goto done;                       \
+  } while (0)
+
+/*
+ * Core code for RFC 3779 2.3 path validation.
+ */
+static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
+                                         STACK_OF(X509) *chain,
+                                         IPAddrBlocks *ext)
+{
+  IPAddrBlocks *child = NULL;
+  int i, j, ret = 1;
+  X509 *x = NULL;
+
+  assert(chain != NULL && sk_X509_num(chain) > 0);
+  assert(ctx != NULL || ext != NULL);
+  assert(ctx == NULL || ctx->verify_cb != NULL);
+
+  /*
+   * Figure out where to start.  If we don't have an extension to
+   * check, we're done.  Otherwise, check canonical form and
+   * set up for walking up the chain.
+   */
+  if (ext != NULL) {
+    i = -1;
+  } else {
+    i = 0;
+    x = sk_X509_value(chain, i);
+    assert(x != NULL);
+    if ((ext = x->rfc3779_addr) == NULL)
+      goto done;
+  }
+  if (!v3_addr_is_canonical(ext))
+    validation_err(X509_V_ERR_INVALID_EXTENSION);
+  sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+  if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
+    X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
+    ret = 0;
+    goto done;
+  }
+
+  /*
+   * Now walk up the chain.  No cert may list resources that its
+   * parent doesn't list.
+   */
+  for (i++; i < sk_X509_num(chain); i++) {
+    x = sk_X509_value(chain, i);
+    assert(x != NULL);
+    if (!v3_addr_is_canonical(x->rfc3779_addr))
+      validation_err(X509_V_ERR_INVALID_EXTENSION);
+    if (x->rfc3779_addr == NULL) {
+      for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+       IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+       if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
+         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+         break;
+       }
+      }
+      continue;
+    }
+    sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+    for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+      IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+      int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
+      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
+      if (fp == NULL) {
+       if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+         break;
+       }
+       continue;
+      }
+      if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+       if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
+           addr_contains(fp->ipAddressChoice->u.addressesOrRanges, 
+                         fc->ipAddressChoice->u.addressesOrRanges,
+                         length_from_afi(v3_addr_get_afi(fc))))
+         sk_IPAddressFamily_set(child, j, fp);
+       else
+         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+  }
+
+  /*
+   * Trust anchor can't inherit.
+   */
+  if (x->rfc3779_addr != NULL) {
+    for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
+      IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
+      if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
+         sk_IPAddressFamily_find(child, fp) >= 0)
+       validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+    }
+  }
+
+ done:
+  sk_IPAddressFamily_free(child);
+  return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
+ */
+int v3_addr_validate_path(X509_STORE_CTX *ctx)
+{
+  return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 2.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+                                 IPAddrBlocks *ext,
+                                 int allow_inheritance)
+{
+  if (ext == NULL)
+    return 1;
+  if (chain == NULL || sk_X509_num(chain) == 0)
+    return 0;
+  if (!allow_inheritance && v3_addr_inherits(ext))
+    return 0;
+  return v3_addr_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
index c481b6f..ac0548b 100644 (file)
@@ -68,7 +68,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
 static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
                        X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
 
-X509V3_EXT_METHOD v3_akey_id =
+const X509V3_EXT_METHOD v3_akey_id =
        {
        NID_authority_key_identifier,
        X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
index b38b3db..bb2f5bc 100644 (file)
@@ -68,7 +68,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
 
-X509V3_EXT_METHOD v3_alt[] = {
+const X509V3_EXT_METHOD v3_alt[] = {
 { NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
 0,0,0,0,
 0,0,
diff --git a/crypto/openssl-0.9/crypto/x509v3/v3_asid.c b/crypto/openssl-0.9/crypto/x509v3/v3_asid.c
new file mode 100644 (file)
index 0000000..271930f
--- /dev/null
@@ -0,0 +1,842 @@
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 3.2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
+ */
+
+ASN1_SEQUENCE(ASRange) = {
+  ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
+  ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ASRange)
+
+ASN1_CHOICE(ASIdOrRange) = {
+  ASN1_SIMPLE(ASIdOrRange, u.id,    ASN1_INTEGER),
+  ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
+} ASN1_CHOICE_END(ASIdOrRange)
+
+ASN1_CHOICE(ASIdentifierChoice) = {
+  ASN1_SIMPLE(ASIdentifierChoice,      u.inherit,       ASN1_NULL),
+  ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
+} ASN1_CHOICE_END(ASIdentifierChoice)
+
+ASN1_SEQUENCE(ASIdentifiers) = {
+  ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
+  ASN1_EXP_OPT(ASIdentifiers, rdi,   ASIdentifierChoice, 1)
+} ASN1_SEQUENCE_END(ASIdentifiers)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
+
+/*
+ * i2r method for an ASIdentifierChoice.
+ */
+static int i2r_ASIdentifierChoice(BIO *out,
+                                 ASIdentifierChoice *choice,
+                                 int indent,
+                                 const char *msg)
+{
+  int i;
+  char *s;
+  if (choice == NULL)
+    return 1;
+  BIO_printf(out, "%*s%s:\n", indent, "", msg);
+  switch (choice->type) {
+  case ASIdentifierChoice_inherit:
+    BIO_printf(out, "%*sinherit\n", indent + 2, "");
+    break;
+  case ASIdentifierChoice_asIdsOrRanges:
+    for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
+      ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+      switch (aor->type) {
+      case ASIdOrRange_id:
+       if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
+         return 0;
+       BIO_printf(out, "%*s%s\n", indent + 2, "", s);
+       OPENSSL_free(s);
+       break;
+      case ASIdOrRange_range:
+       if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
+         return 0;
+       BIO_printf(out, "%*s%s-", indent + 2, "", s);
+       OPENSSL_free(s);
+       if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
+         return 0;
+       BIO_printf(out, "%s\n", s);
+       OPENSSL_free(s);
+       break;
+      default:
+       return 0;
+      }
+    }
+    break;
+  default:
+    return 0;
+  }
+  return 1;
+}
+
+/*
+ * i2r method for an ASIdentifier extension.
+ */
+static int i2r_ASIdentifiers(X509V3_EXT_METHOD *method,
+                            void *ext,
+                            BIO *out,
+                            int indent)
+{
+  ASIdentifiers *asid = ext;
+  return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
+                                "Autonomous System Numbers") &&
+         i2r_ASIdentifierChoice(out, asid->rdi, indent,
+                                "Routing Domain Identifiers"));
+}
+
+/*
+ * Sort comparision function for a sequence of ASIdOrRange elements.
+ */
+static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
+                          const ASIdOrRange * const *b_)
+{
+  const ASIdOrRange *a = *a_, *b = *b_;
+
+  assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
+        (a->type == ASIdOrRange_range && a->u.range != NULL &&
+         a->u.range->min != NULL && a->u.range->max != NULL));
+
+  assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
+        (b->type == ASIdOrRange_range && b->u.range != NULL &&
+         b->u.range->min != NULL && b->u.range->max != NULL));
+
+  if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
+    return ASN1_INTEGER_cmp(a->u.id, b->u.id);
+
+  if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
+    int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
+    return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
+  }
+
+  if (a->type == ASIdOrRange_id)
+    return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
+  else
+    return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
+}
+
+/*
+ * Add an inherit element.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which)
+{
+  ASIdentifierChoice **choice;
+  if (asid == NULL)
+    return 0;
+  switch (which) {
+  case V3_ASID_ASNUM:
+    choice = &asid->asnum;
+    break;
+  case V3_ASID_RDI:
+    choice = &asid->rdi;
+    break;
+  default:
+    return 0;
+  }
+  if (*choice == NULL) {
+    if ((*choice = ASIdentifierChoice_new()) == NULL)
+      return 0;
+    assert((*choice)->u.inherit == NULL);
+    if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+      return 0;
+    (*choice)->type = ASIdentifierChoice_inherit;
+  }
+  return (*choice)->type == ASIdentifierChoice_inherit;
+}
+
+/*
+ * Add an ID or range to an ASIdentifierChoice.
+ */
+int v3_asid_add_id_or_range(ASIdentifiers *asid,
+                           int which,
+                           ASN1_INTEGER *min,
+                           ASN1_INTEGER *max)
+{
+  ASIdentifierChoice **choice;
+  ASIdOrRange *aor;
+  if (asid == NULL)
+    return 0;
+  switch (which) {
+  case V3_ASID_ASNUM:
+    choice = &asid->asnum;
+    break;
+  case V3_ASID_RDI:
+    choice = &asid->rdi;
+    break;
+  default:
+    return 0;
+  }
+  if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+    return 0;
+  if (*choice == NULL) {
+    if ((*choice = ASIdentifierChoice_new()) == NULL)
+      return 0;
+    assert((*choice)->u.asIdsOrRanges == NULL);
+    (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
+    if ((*choice)->u.asIdsOrRanges == NULL)
+      return 0;
+    (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
+  }
+  if ((aor = ASIdOrRange_new()) == NULL)
+    return 0;
+  if (max == NULL) {
+    aor->type = ASIdOrRange_id;
+    aor->u.id = min;
+  } else {
+    aor->type = ASIdOrRange_range;
+    if ((aor->u.range = ASRange_new()) == NULL)
+      goto err;
+    ASN1_INTEGER_free(aor->u.range->min);
+    aor->u.range->min = min;
+    ASN1_INTEGER_free(aor->u.range->max);
+    aor->u.range->max = max;
+  }
+  if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+    goto err;
+  return 1;
+
+ err:
+  ASIdOrRange_free(aor);
+  return 0;
+}
+
+/*
+ * Extract min and max values from an ASIdOrRange.
+ */
+static void extract_min_max(ASIdOrRange *aor,
+                           ASN1_INTEGER **min,
+                           ASN1_INTEGER **max)
+{
+  assert(aor != NULL && min != NULL && max != NULL);
+  switch (aor->type) {
+  case ASIdOrRange_id:
+    *min = aor->u.id;
+    *max = aor->u.id;
+    return;
+  case ASIdOrRange_range:
+    *min = aor->u.range->min;
+    *max = aor->u.range->max;
+    return;
+  }
+}
+
+/*
+ * Check whether an ASIdentifierChoice is in canonical form.
+ */
+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
+{
+  ASN1_INTEGER *a_max_plus_one = NULL;
+  BIGNUM *bn = NULL;
+  int i, ret = 0;
+
+  /*
+   * Empty element or inheritance is canonical.
+   */
+  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+    return 1;
+
+  /*
+   * If not a list, or if empty list, it's broken.
+   */
+  if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+      sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
+    return 0;
+
+  /*
+   * It's a list, check it.
+   */
+  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+    extract_min_max(a, &a_min, &a_max);
+    extract_min_max(b, &b_min, &b_max);
+
+    /*
+     * Punt misordered list, overlapping start, or inverted range.
+     */
+    if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
+       ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+       ASN1_INTEGER_cmp(b_min, b_max) > 0)
+      goto done;
+
+    /*
+     * Calculate a_max + 1 to check for adjacency.
+     */
+    if ((bn == NULL && (bn = BN_new()) == NULL) ||
+       ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+       !BN_add_word(bn, 1) ||
+       (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
+               ERR_R_MALLOC_FAILURE);
+      goto done;
+    }
+    
+    /*
+     * Punt if adjacent or overlapping.
+     */
+    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
+      goto done;
+  }
+
+  ret = 1;
+
+ done:
+  ASN1_INTEGER_free(a_max_plus_one);
+  BN_free(bn);
+  return ret;
+}
+
+/*
+ * Check whether an ASIdentifier extension is in canonical form.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid)
+{
+  return (asid == NULL ||
+         (ASIdentifierChoice_is_canonical(asid->asnum) ||
+          ASIdentifierChoice_is_canonical(asid->rdi)));
+}
+
+/*
+ * Whack an ASIdentifierChoice into canonical form.
+ */
+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
+{
+  ASN1_INTEGER *a_max_plus_one = NULL;
+  BIGNUM *bn = NULL;
+  int i, ret = 0;
+
+  /*
+   * Nothing to do for empty element or inheritance.
+   */
+  if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+    return 1;
+
+  /*
+   * We have a list.  Sort it.
+   */
+  assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
+  sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
+
+  /*
+   * Now check for errors and suboptimal encoding, rejecting the
+   * former and fixing the latter.
+   */
+  for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+    ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+    ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+    ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+    extract_min_max(a, &a_min, &a_max);
+    extract_min_max(b, &b_min, &b_max);
+
+    /*
+     * Make sure we're properly sorted (paranoia).
+     */
+    assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
+
+    /*
+     * Check for overlaps.
+     */
+    if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+               X509V3_R_EXTENSION_VALUE_ERROR);
+      goto done;
+    }
+
+    /*
+     * Calculate a_max + 1 to check for adjacency.
+     */
+    if ((bn == NULL && (bn = BN_new()) == NULL) ||
+       ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+       !BN_add_word(bn, 1) ||
+       (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+      X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
+      goto done;
+    }
+    
+    /*
+     * If a and b are adjacent, merge them.
+     */
+    if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
+      ASRange *r;
+      switch (a->type) {
+      case ASIdOrRange_id:
+       if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
+         X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+                   ERR_R_MALLOC_FAILURE);
+         goto done;
+       }
+       r->min = a_min;
+       r->max = b_max;
+       a->type = ASIdOrRange_range;
+       a->u.range = r;
+       break;
+      case ASIdOrRange_range:
+       ASN1_INTEGER_free(a->u.range->max);
+       a->u.range->max = b_max;
+       break;
+      }
+      switch (b->type) {
+      case ASIdOrRange_id:
+       b->u.id = NULL;
+       break;
+      case ASIdOrRange_range:
+       b->u.range->max = NULL;
+       break;
+      }
+      ASIdOrRange_free(b);
+      sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+      i--;
+      continue;
+    }
+  }
+
+  assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
+
+  ret = 1;
+
+ done:
+  ASN1_INTEGER_free(a_max_plus_one);
+  BN_free(bn);
+  return ret;
+}
+
+/*
+ * Whack an ASIdentifier extension into canonical form.
+ */
+int v3_asid_canonize(ASIdentifiers *asid)
+{
+  return (asid == NULL ||
+         (ASIdentifierChoice_canonize(asid->asnum) &&
+          ASIdentifierChoice_canonize(asid->rdi)));
+}
+
+/*
+ * v2i method for an ASIdentifier extension.
+ */
+static void *v2i_ASIdentifiers(struct v3_ext_method *method,
+                              struct v3_ext_ctx *ctx,
+                              STACK_OF(CONF_VALUE) *values)
+{
+  ASIdentifiers *asid = NULL;
+  int i;
+
+  if ((asid = ASIdentifiers_new()) == NULL) {
+    X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+
+  for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+    CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+    ASN1_INTEGER *min = NULL, *max = NULL;
+    int i1, i2, i3, is_range, which;
+
+    /*
+     * Figure out whether this is an AS or an RDI.
+     */
+    if (       !name_cmp(val->name, "AS")) {
+      which = V3_ASID_ASNUM;
+    } else if (!name_cmp(val->name, "RDI")) {
+      which = V3_ASID_RDI;
+    } else {
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    /*
+     * Handle inheritance.
+     */
+    if (!strcmp(val->value, "inherit")) {
+      if (v3_asid_add_inherit(asid, which))
+       continue;
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
+      X509V3_conf_err(val);
+      goto err;
+    }
+
+    /*
+     * Number, range, or mistake, pick it apart and figure out which.
+     */
+    i1 = strspn(val->value, "0123456789");
+    if (val->value[i1] == '\0') {
+      is_range = 0;
+    } else {
+      is_range = 1;
+      i2 = i1 + strspn(val->value + i1, " \t");
+      if (val->value[i2] != '-') {
+       X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
+       X509V3_conf_err(val);
+       goto err;
+      }
+      i2++;
+      i2 = i2 + strspn(val->value + i2, " \t");
+      i3 = i2 + strspn(val->value + i2, "0123456789");
+      if (val->value[i3] != '\0') {
+       X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
+       X509V3_conf_err(val);
+       goto err;
+      }
+    }
+
+    /*
+     * Syntax is ok, read and add it.
+     */
+    if (!is_range) {
+      if (!X509V3_get_value_int(val, &min)) {
+       X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+    } else {
+      char *s = BUF_strdup(val->value);
+      if (s == NULL) {
+       X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+      s[i1] = '\0';
+      min = s2i_ASN1_INTEGER(NULL, s);
+      max = s2i_ASN1_INTEGER(NULL, s + i2);
+      OPENSSL_free(s);
+      if (min == NULL || max == NULL) {
+       ASN1_INTEGER_free(min);
+       ASN1_INTEGER_free(max);
+       X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+       goto err;
+      }
+    }
+    if (!v3_asid_add_id_or_range(asid, which, min, max)) {
+      ASN1_INTEGER_free(min);
+      ASN1_INTEGER_free(max);
+      X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+      goto err;
+    }
+  }
+
+  /*
+   * Canonize the result, then we're done.
+   */
+  if (!v3_asid_canonize(asid))
+    goto err;
+  return asid;
+
+ err:
+  ASIdentifiers_free(asid);
+  return NULL;
+}
+
+/*
+ * OpenSSL dispatch.
+ */
+const X509V3_EXT_METHOD v3_asid = {
+  NID_sbgp_autonomousSysNum,   /* nid */
+  0,                           /* flags */
+  ASN1_ITEM_ref(ASIdentifiers),        /* template */
+  0, 0, 0, 0,                  /* old functions, ignored */
+  0,                           /* i2s */
+  0,                           /* s2i */
+  0,                           /* i2v */
+  v2i_ASIdentifiers,           /* v2i */
+  i2r_ASIdentifiers,           /* i2r */
+  0,                           /* r2i */
+  NULL                         /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension uses inheritance.
+ */
+int v3_asid_inherits(ASIdentifiers *asid)
+{
+  return (asid != NULL &&
+         ((asid->asnum != NULL &&
+           asid->asnum->type == ASIdentifierChoice_inherit) ||
+          (asid->rdi != NULL &&
+           asid->rdi->type == ASIdentifierChoice_inherit)));
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
+{
+  ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
+  int p, c;
+
+  if (child == NULL || parent == child)
+    return 1;
+  if (parent == NULL)
+    return 0;
+
+  p = 0;
+  for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
+    extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
+    for (;; p++) {
+      if (p >= sk_ASIdOrRange_num(parent))
+       return 0;
+      extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
+      if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
+       continue;
+      if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
+       return 0;
+      break;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * Test whether a is a subet of b.
+ */
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
+{
+  return (a == NULL ||
+         a == b ||
+         (b != NULL &&
+          !v3_asid_inherits(a) &&
+          !v3_asid_inherits(b) &&
+          asid_contains(b->asnum->u.asIdsOrRanges,
+                        a->asnum->u.asIdsOrRanges) &&
+          asid_contains(b->rdi->u.asIdsOrRanges,
+                        a->rdi->u.asIdsOrRanges)));
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)          \
+  do {                                 \
+    if (ctx != NULL) {                 \
+      ctx->error = _err_;              \
+      ctx->error_depth = i;            \
+      ctx->current_cert = x;           \
+      ret = ctx->verify_cb(0, ctx);    \
+    } else {                           \
+      ret = 0;                         \
+    }                                  \
+    if (!ret)                          \
+      goto done;                       \
+  } while (0)
+
+/*
+ * Core code for RFC 3779 3.3 path validation.
+ */
+static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
+                                         STACK_OF(X509) *chain,
+                                         ASIdentifiers *ext)
+{
+  ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
+  int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
+  X509 *x = NULL;
+
+  assert(chain != NULL && sk_X509_num(chain) > 0);
+  assert(ctx != NULL || ext != NULL);
+  assert(ctx == NULL || ctx->verify_cb != NULL);
+
+  /*
+   * Figure out where to start.  If we don't have an extension to
+   * check, we're done.  Otherwise, check canonical form and
+   * set up for walking up the chain.
+   */
+  if (ext != NULL) {
+    i = -1;
+  } else {
+    i = 0;
+    x = sk_X509_value(chain, i);
+    assert(x != NULL);
+    if ((ext = x->rfc3779_asid) == NULL)
+      goto done;
+  }
+  if (!v3_asid_is_canonical(ext))
+    validation_err(X509_V_ERR_INVALID_EXTENSION);
+  if (ext->asnum != NULL)  {
+    switch (ext->asnum->type) {
+    case ASIdentifierChoice_inherit:
+      inherit_as = 1;
+      break;
+    case ASIdentifierChoice_asIdsOrRanges:
+      child_as = ext->asnum->u.asIdsOrRanges;
+      break;
+    }
+  }
+  if (ext->rdi != NULL) {
+    switch (ext->rdi->type) {
+    case ASIdentifierChoice_inherit:
+      inherit_rdi = 1;
+      break;
+    case ASIdentifierChoice_asIdsOrRanges:
+      child_rdi = ext->rdi->u.asIdsOrRanges;
+      break;
+    }
+  }
+
+  /*
+   * Now walk up the chain.  Extensions must be in canonical form, no
+   * cert may list resources that its parent doesn't list.
+   */
+  for (i++; i < sk_X509_num(chain); i++) {
+    x = sk_X509_value(chain, i);
+    assert(x != NULL);
+    if (x->rfc3779_asid == NULL) {
+      if (child_as != NULL || child_rdi != NULL)
+       validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      continue;
+    }
+    if (!v3_asid_is_canonical(x->rfc3779_asid))
+      validation_err(X509_V_ERR_INVALID_EXTENSION);
+    if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      child_as = NULL;
+      inherit_as = 0;
+    }
+    if (x->rfc3779_asid->asnum != NULL &&
+       x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
+      if (inherit_as ||
+         asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
+       child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+       inherit_as = 0;
+      } else {
+       validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+    if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      child_rdi = NULL;
+      inherit_rdi = 0;
+    }
+    if (x->rfc3779_asid->rdi != NULL &&
+       x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+      if (inherit_rdi ||
+         asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
+       child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+       inherit_rdi = 0;
+      } else {
+       validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+      }
+    }
+  }
+
+  /*
+   * Trust anchor can't inherit.
+   */
+  if (x->rfc3779_asid != NULL) {
+    if (x->rfc3779_asid->asnum != NULL &&
+       x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+    if (x->rfc3779_asid->rdi != NULL &&
+       x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
+      validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+  }
+
+ done:
+  return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
+ */
+int v3_asid_validate_path(X509_STORE_CTX *ctx)
+{
+  return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 3.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+                                 ASIdentifiers *ext,
+                                 int allow_inheritance)
+{
+  if (ext == NULL)
+    return 1;
+  if (chain == NULL || sk_X509_num(chain) == 0)
+    return 0;
+  if (!allow_inheritance && v3_asid_inherits(ext))
+    return 0;
+  return v3_asid_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
index cbb0127..74b1233 100644 (file)
@@ -67,7 +67,7 @@
 static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
 static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
 
-X509V3_EXT_METHOD v3_bcons = {
+const X509V3_EXT_METHOD v3_bcons = {
 NID_basic_constraints, 0,
 ASN1_ITEM_ref(BASIC_CONSTRAINTS),
 0,0,0,0,
index 170c8d2..cf31f08 100644 (file)
@@ -88,8 +88,8 @@ static BIT_STRING_BITNAME key_usage_type_table[] = {
 
 
 
-X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
-X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);
 
 STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
             ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
index e5b8c5a..a40f490 100644 (file)
@@ -77,7 +77,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
                                        STACK_OF(CONF_VALUE) *unot, int ia5org);
 static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
 
-X509V3_EXT_METHOD v3_cpols = {
+const X509V3_EXT_METHOD v3_cpols = {
 NID_certificate_policies, 0,ASN1_ITEM_ref(CERTIFICATEPOLICIES),
 0,0,0,0,
 0,0,
index f90829c..c6e3eba 100644 (file)
@@ -68,7 +68,7 @@ static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method,
 static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
                                X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 
-X509V3_EXT_METHOD v3_crld = {
+const X509V3_EXT_METHOD v3_crld = {
 NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS),
 0,0,0,0,
 0,0,
index 010c9d6..a236cb2 100644 (file)
@@ -72,7 +72,7 @@ static ENUMERATED_NAMES crl_reasons[] = {
 {-1, NULL, NULL}
 };
 
-X509V3_EXT_METHOD v3_crl_reason = { 
+const X509V3_EXT_METHOD v3_crl_reason = { 
 NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
 0,0,0,0,
 (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
index 58c1c2e..a4efe00 100644 (file)
@@ -68,7 +68,7 @@ static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
 static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
                void *eku, STACK_OF(CONF_VALUE) *extlist);
 
-X509V3_EXT_METHOD v3_ext_ku = {
+const X509V3_EXT_METHOD v3_ext_ku = {
        NID_ext_key_usage, 0,
        ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
        0,0,0,0,
@@ -80,7 +80,7 @@ X509V3_EXT_METHOD v3_ext_ku = {
 };
 
 /* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
-X509V3_EXT_METHOD v3_ocsp_accresp = {
+const X509V3_EXT_METHOD v3_ocsp_accresp = {
        NID_id_pkix_OCSP_acceptableResponses, 0,
        ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
        0,0,0,0,