New utility pkeyparam. Enhance and bugfix algorithm specific parameter
authorDr. Stephen Henson <steve@openssl.org>
Tue, 28 Mar 2006 14:35:32 +0000 (14:35 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 28 Mar 2006 14:35:32 +0000 (14:35 +0000)
functions to support it.

18 files changed:
CHANGES
apps/Makefile
apps/pkey.c
apps/pkeyparam.c [new file with mode: 0644]
apps/progs.h
crypto/dh/dh.h
crypto/dh/dh_ameth.c
crypto/dh/dh_err.c
crypto/dh/dh_prn.c
crypto/dsa/dsa.h
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_err.c
crypto/ec/ec.h
crypto/ec/ec_ameth.c
crypto/ec/ec_err.c
crypto/pem/pem.h
crypto/pem/pem_lib.c
crypto/pem/pem_pkey.c

diff --git a/CHANGES b/CHANGES
index 5a10115..bb006e2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,8 +4,9 @@
 
  Changes between 0.9.8a and 0.9.9  [xx XXX xxxx]
 
-  *) New utility 'pkey'. This is similar to algorithm specific utilities
-     such as 'rsa', 'dsa' etc except it processes any key type.
+  *) New utilities pkey and pkeyparam. These are similar to algorithm specific
+     utilities such as rsa, dsa, dsaparam etc except they processes any key
+     type.
      [Steve Henson]
 
   *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New 
index 466173e..57be61e 100644 (file)
@@ -39,7 +39,7 @@ E_EXE=        verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
        ca crl rsa rsautl dsa dsaparam ec ecparam \
        x509 genrsa gendsa s_server s_client speed \
        s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
-       pkcs8 pkey spkac smime rand engine ocsp prime ts
+       pkcs8 pkey pkeyparam spkac smime rand engine ocsp prime ts
 
 PROGS= $(PROGRAM).c
 
@@ -55,7 +55,7 @@ E_OBJ=        verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o er
        rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
        x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
        s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
-       ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o \
+       ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o \
        spkac.o smime.o rand.o engine.o ocsp.o prime.o ts.o
 
 E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
@@ -63,7 +63,7 @@ E_SRC=        verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.
        rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \
        x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
        s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
-       ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c \
+       ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c \
        spkac.c smime.c rand.c engine.c ocsp.c prime.c ts.c
 
 SRC=$(E_SRC)
index b34974b..e53b43a 100644 (file)
@@ -1,4 +1,4 @@
-/* pkey.c */
+/* apps/pkey.c */
 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
  * project 2006
  */
@@ -81,6 +81,7 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_ENGINE
        char *engine=NULL;
 #endif
+       int ret = 1;
 
        if (bio_err == NULL)
                bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
@@ -203,7 +204,7 @@ int MAIN(int argc, char **argv)
        if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
                {
                BIO_printf(bio_err, "Error getting passwords\n");
-               return 1;
+               goto end;
                }
 
        if (outfile)
@@ -212,7 +213,7 @@ int MAIN(int argc, char **argv)
                        {
                        BIO_printf(bio_err,
                                 "Can't open output file %s\n", outfile);
-                       return (1);
+                       goto end;
                        }
                }
        else
@@ -233,10 +234,7 @@ int MAIN(int argc, char **argv)
                pkey = load_key(bio_err, infile, informat, 1,
                        passin, e, "key");
        if (!pkey)
-               {
-               BIO_free_all(out);
-               return 1;
-               }
+               goto end;
 
        if (!noout)
                {
@@ -258,7 +256,7 @@ int MAIN(int argc, char **argv)
                else
                        {
                        BIO_printf(bio_err, "Bad format specified for key\n");
-                               return (1);
+                       goto end;
                        }
 
                }
@@ -271,6 +269,8 @@ int MAIN(int argc, char **argv)
                        EVP_PKEY_print_private(out, pkey, 0, NULL);
                }
 
+       ret = 0;
+
        end:
        EVP_PKEY_free(pkey);
        BIO_free_all(out);
@@ -280,5 +280,5 @@ int MAIN(int argc, char **argv)
        if (passout)
                OPENSSL_free(passout);
 
-       return (0);
+       return ret;
        }
diff --git a/apps/pkeyparam.c b/apps/pkeyparam.c
new file mode 100644 (file)
index 0000000..15a8a2b
--- /dev/null
@@ -0,0 +1,197 @@
+/* apps/pkeyparam.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkeyparam_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+       {
+       ENGINE *e = NULL;
+       char **args, *infile = NULL, *outfile = NULL;
+       BIO *in = NULL, *out = NULL;
+       int text = 0, noout = 0;
+       EVP_PKEY *pkey=NULL;
+       int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+       char *engine=NULL;
+#endif
+       int ret = 1;
+
+       if (bio_err == NULL)
+               bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+       if (!load_config(bio_err, NULL))
+               goto end;
+
+       ERR_load_crypto_strings();
+       OpenSSL_add_all_algorithms();
+       args = argv + 1;
+       while (!badarg && *args && *args[0] == '-')
+               {
+               if (!strcmp (*args, "-in"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               infile = *args;
+                               }
+                       else badarg = 1;
+                       }
+               else if (!strcmp (*args, "-out"))
+                       {
+                       if (args[1])
+                               {
+                               args++;
+                               outfile = *args;
+                               }
+                       else badarg = 1;
+                       }
+#ifndef OPENSSL_NO_ENGINE
+               else if (strcmp(*args,"-engine") == 0)
+                       {
+                       if (!args[1]) goto bad;
+                       engine= *(++args);
+                       }
+#endif
+
+               else if (strcmp(*args,"-text") == 0)
+                       text=1;
+               else if (strcmp(*args,"-noout") == 0)
+                       noout=1;
+               args++;
+               }
+
+       if (badarg)
+               {
+               bad:
+               BIO_printf(bio_err, "Usage pkeyparam [options]\n");
+               BIO_printf(bio_err, "where options are\n");
+               BIO_printf(bio_err, "-in file        input file\n");
+               BIO_printf(bio_err, "-out file       output file\n");
+#ifndef OPENSSL_NO_ENGINE
+               BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+               return 1;
+               }
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+       if (infile)
+               {
+               if (!(in = BIO_new_file (infile, "r")))
+                       {
+                       BIO_printf(bio_err,
+                                "Can't open input file %s\n", infile);
+                       goto end;
+                       }
+               }
+       else
+               in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+       if (outfile)
+               {
+               if (!(out = BIO_new_file (outfile, "w")))
+                       {
+                       BIO_printf(bio_err,
+                                "Can't open output file %s\n", outfile);
+                       goto end;
+                       }
+               }
+       else
+               {
+               out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+                       {
+                       BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+                       out = BIO_push(tmpbio, out);
+                       }
+#endif
+               }
+
+       pkey = PEM_read_bio_Parameters(in, NULL);
+       if (!pkey)
+               {
+               BIO_printf(bio_err, "Error reading paramters\n");
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+
+       if (!noout)
+               PEM_write_bio_Parameters(out,pkey);
+
+       if (text)
+               EVP_PKEY_print_params(out, pkey, 0, NULL);
+
+       ret = 0;
+
+       end:
+       EVP_PKEY_free(pkey);
+       BIO_free_all(out);
+       BIO_free(in);
+
+       return ret;
+       }
index 2db1c68..67cc6df 100644 (file)
@@ -35,6 +35,7 @@ extern int nseq_main(int argc,char *argv[]);
 extern int pkcs12_main(int argc,char *argv[]);
 extern int pkcs8_main(int argc,char *argv[]);
 extern int pkey_main(int argc,char *argv[]);
+extern int pkeyparam_main(int argc,char *argv[]);
 extern int spkac_main(int argc,char *argv[]);
 extern int smime_main(int argc,char *argv[]);
 extern int rand_main(int argc,char *argv[]);
@@ -122,6 +123,7 @@ FUNCTION functions[] = {
 #endif
        {FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
        {FUNC_TYPE_GENERAL,"pkey",pkey_main},
+       {FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
        {FUNC_TYPE_GENERAL,"spkac",spkac_main},
        {FUNC_TYPE_GENERAL,"smime",smime_main},
        {FUNC_TYPE_GENERAL,"rand",rand_main},
index 7871882..48b6283 100644 (file)
@@ -215,13 +215,14 @@ void ERR_load_DH_strings(void);
 #define DH_F_DHPARAMS_PRINT_FP                          101
 #define DH_F_DH_BUILTIN_GENPARAMS                       106
 #define DH_F_DH_NEW_METHOD                              105
+#define DH_F_DH_PARAM_DECODE                            107
 #define DH_F_GENERATE_KEY                               103
 #define DH_F_GENERATE_PARAMETERS                        104
 
 /* Reason codes. */
 #define DH_R_BAD_GENERATOR                              101
-#define DH_R_NO_PRIVATE_VALUE                           100
 #define DH_R_INVALID_PUBKEY                             102
+#define DH_R_NO_PRIVATE_VALUE                           100
 
 #ifdef  __cplusplus
 }
index bcc56a1..ba3ff56 100644 (file)
@@ -67,6 +67,82 @@ static void int_dh_free(EVP_PKEY *pkey)
        DH_free(pkey->pkey.dh);
        }
 
+static int dh_param_decode(EVP_PKEY *pkey,
+                                       const unsigned char **pder, int derlen)
+       {
+       DH *dh;
+       if (!(dh = d2i_DHparams(NULL, pder, derlen)))
+               {
+               DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+               return 0;
+               }
+       EVP_PKEY_assign_DH(pkey, dh);
+       return 1;
+       }
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+       {
+       return i2d_DHparams(pkey->pkey.dh, pder);
+       }
+
+static int do_dhparam_print(BIO *bp, const DH *x, int indent,
+                                                       ASN1_PCTX *ctx)
+       {
+       unsigned char *m=NULL;
+       int reason=ERR_R_BUF_LIB,ret=0;
+       size_t buf_len=0, i;
+
+       if (x->p)
+               buf_len = (size_t)BN_num_bytes(x->p);
+       else
+               {
+               reason = ERR_R_PASSED_NULL_PARAMETER;
+               goto err;
+               }
+       if (x->g)
+               if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
+                       buf_len = i;
+       m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+       if (m == NULL)
+               {
+               reason=ERR_R_MALLOC_FAILURE;
+               goto err;
+               }
+
+       BIO_indent(bp, indent, 128);
+       if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
+               BN_num_bits(x->p)) <= 0)
+               goto err;
+       indent += 4;
+       if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
+       if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
+       if (x->length != 0)
+               {
+               BIO_indent(bp, indent, 128);
+               if (BIO_printf(bp,"recommended-private-length: %d bits\n",
+                       (int)x->length) <= 0) goto err;
+               }
+       ret=1;
+       if (0)
+               {
+err:
+               DHerr(DH_F_DHPARAMS_PRINT,reason);
+               }
+       if (m != NULL) OPENSSL_free(m);
+       return(ret);
+       }
+
+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                                                       ASN1_PCTX *ctx)
+       {
+       return do_dhparam_print(bp, pkey->pkey.dh, indent, ctx);
+       }
+
+int DHparams_print(BIO *bp, const DH *x)
+       {
+       return do_dhparam_print(bp, x, 4, NULL);
+       }
+
 const EVP_PKEY_ASN1_METHOD dh_asn1_meth = 
        {
        EVP_PKEY_DH,
@@ -88,7 +164,10 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
        0,
        0,
 
-       0,0,0,0,0,0,
+       dh_param_decode,
+       dh_param_encode,
+       0,0,0,
+       dh_param_print,
 
        int_dh_free,
        0
index ea67fb7..4e4deb6 100644 (file)
@@ -75,6 +75,7 @@ static ERR_STRING_DATA DH_str_functs[]=
 {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP),     "DHparams_print_fp"},
 {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),  "DH_BUILTIN_GENPARAMS"},
 {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
+{ERR_FUNC(DH_F_DH_PARAM_DECODE),       "DH_PARAM_DECODE"},
 {ERR_FUNC(DH_F_GENERATE_KEY),  "GENERATE_KEY"},
 {ERR_FUNC(DH_F_GENERATE_PARAMETERS),   "GENERATE_PARAMETERS"},
 {0,NULL}
@@ -83,8 +84,8 @@ static ERR_STRING_DATA DH_str_functs[]=
 static ERR_STRING_DATA DH_str_reasons[]=
        {
 {ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
-{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
 {ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
+{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
 {0,NULL}
        };
 
index 04e7c55..ae58c2a 100644 (file)
@@ -78,47 +78,3 @@ int DHparams_print_fp(FILE *fp, const DH *x)
        return(ret);
        }
 #endif
-
-int DHparams_print(BIO *bp, const DH *x)
-       {
-       unsigned char *m=NULL;
-       int reason=ERR_R_BUF_LIB,ret=0;
-       size_t buf_len=0, i;
-
-       if (x->p)
-               buf_len = (size_t)BN_num_bytes(x->p);
-       else
-               {
-               reason = ERR_R_PASSED_NULL_PARAMETER;
-               goto err;
-               }
-       if (x->g)
-               if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
-                       buf_len = i;
-       m=(unsigned char *)OPENSSL_malloc(buf_len+10);
-       if (m == NULL)
-               {
-               reason=ERR_R_MALLOC_FAILURE;
-               goto err;
-               }
-
-       if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
-               BN_num_bits(x->p)) <= 0)
-               goto err;
-       if (!ASN1_bn_print(bp,"prime:",x->p,m,4)) goto err;
-       if (!ASN1_bn_print(bp,"generator:",x->g,m,4)) goto err;
-       if (x->length != 0)
-               {
-               if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
-                       (int)x->length) <= 0) goto err;
-               }
-       ret=1;
-       if (0)
-               {
-err:
-               DHerr(DH_F_DHPARAMS_PRINT,reason);
-               }
-       if (m != NULL) OPENSSL_free(m);
-       return(ret);
-       }
-
index 5ee83e3..502b489 100644 (file)
@@ -260,6 +260,7 @@ void ERR_load_DSA_strings(void);
 #define DSA_F_DSA_DO_SIGN                               112
 #define DSA_F_DSA_DO_VERIFY                             113
 #define DSA_F_DSA_NEW_METHOD                            103
+#define DSA_F_DSA_PARAM_DECODE                          119
 #define DSA_F_DSA_PRINT                                         104
 #define DSA_F_DSA_PRINT_FP                              105
 #define DSA_F_DSA_PRIV_DECODE                           115
index 3198224..9d55665 100644 (file)
@@ -473,6 +473,23 @@ err:
        return(ret);
        }
 
+static int dsa_param_decode(EVP_PKEY *pkey,
+                                       const unsigned char **pder, int derlen)
+       {
+       DSA *dsa;
+       if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
+               {
+               DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
+               return 0;
+               }
+       EVP_PKEY_assign_DSA(pkey, dsa);
+       return 1;
+       }
+
+static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+       {
+       return i2d_DSAparams(pkey->pkey.dsa, pder);
+       }
 
 static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                                                        ASN1_PCTX *ctx)
@@ -560,7 +577,8 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
                int_dsa_size,
                dsa_bits,
 
-               0,0,
+               dsa_param_decode,
+               dsa_param_encode,
                dsa_missing_parameters,
                dsa_copy_parameters,
                dsa_cmp_parameters,
index 920cabf..492c8fa 100644 (file)
@@ -76,6 +76,7 @@ static ERR_STRING_DATA DSA_str_functs[]=
 {ERR_FUNC(DSA_F_DSA_DO_SIGN),  "DSA_do_sign"},
 {ERR_FUNC(DSA_F_DSA_DO_VERIFY),        "DSA_do_verify"},
 {ERR_FUNC(DSA_F_DSA_NEW_METHOD),       "DSA_new_method"},
+{ERR_FUNC(DSA_F_DSA_PARAM_DECODE),     "DSA_PARAM_DECODE"},
 {ERR_FUNC(DSA_F_DSA_PRINT),    "DSA_print"},
 {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
 {ERR_FUNC(DSA_F_DSA_PRIV_DECODE),      "DSA_PRIV_DECODE"},
index a5ec630..b937f64 100644 (file)
@@ -919,6 +919,7 @@ void ERR_load_EC_strings(void);
 #define EC_F_D2I_ECPKPARAMETERS                                 145
 #define EC_F_D2I_ECPRIVATEKEY                           146
 #define EC_F_ECKEY_PARAM2TYPE                           211
+#define EC_F_ECKEY_PARAM_DECODE                                 196
 #define EC_F_ECKEY_PRIV_DECODE                          212
 #define EC_F_ECKEY_PRIV_ENCODE                          213
 #define EC_F_ECKEY_PUB_DECODE                           214
index 2fee623..18c4265 100644 (file)
@@ -515,6 +515,24 @@ err:
        return(ret);
        }
 
+static int eckey_param_decode(EVP_PKEY *pkey,
+                                       const unsigned char **pder, int derlen)
+       {
+       EC_KEY *eckey;
+       if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
+               {
+               ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+               return 0;
+               }
+       EVP_PKEY_assign_EC_KEY(pkey, eckey);
+       return 1;
+       }
+
+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+       {
+       return i2d_ECParameters(pkey->pkey.ec, pder);
+       }
+
 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                                                        ASN1_PCTX *ctx)
        {
@@ -572,7 +590,8 @@ EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
        int_ec_size,
        ec_bits,
 
-       0,0,    
+       eckey_param_decode,
+       eckey_param_encode,
        ec_missing_parameters,
        ec_copy_parameters,
        ec_cmp_parameters,
index 18a300d..78dbf48 100644 (file)
@@ -74,6 +74,13 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_FUNC(EC_F_D2I_ECPARAMETERS),      "d2i_ECParameters"},
 {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS),    "d2i_ECPKParameters"},
 {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY),      "d2i_ECPrivateKey"},
+{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE),      "ECKEY_PARAM2TYPE"},
+{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE),    "ECKEY_PARAM_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE),     "ECKEY_PRIV_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE),     "ECKEY_PRIV_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_DECODE),      "ECKEY_PUB_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE),      "ECKEY_PUB_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM),      "ECKEY_TYPE2PARAM"},
 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT),    "ECParameters_print"},
 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
 {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT),  "ECPKParameters_print"},
@@ -88,6 +95,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS),    "EC_ASN1_GROUP2PKPARAMETERS"},
 {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP),      "EC_ASN1_PARAMETERS2GROUP"},
 {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP),    "EC_ASN1_PKPARAMETERS2GROUP"},
+{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA),   "EC_EX_DATA_set_data"},
 {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),     "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),       "ec_GF2m_simple_group_check_discriminant"},
 {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),        "ec_GF2m_simple_group_set_curve"},
@@ -137,7 +145,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT),      "EC_GROUP_precompute_mult"},
 {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M),       "EC_GROUP_set_curve_GF2m"},
 {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP),        "EC_GROUP_set_curve_GFp"},
-{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA),   "EC_EX_DATA_set_data"},
+{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA),       "EC_GROUP_SET_EXTRA_DATA"},
 {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR),        "EC_GROUP_set_generator"},
 {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY),      "EC_KEY_check_key"},
 {ERR_FUNC(EC_F_EC_KEY_COPY),   "EC_KEY_copy"},
@@ -185,6 +193,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
 {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD)     ,"asn1 unknown field"},
 {ERR_REASON(EC_R_BUFFER_TOO_SMALL)       ,"buffer too small"},
 {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
+{ERR_REASON(EC_R_DECODE_ERROR)           ,"decode error"},
 {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO)   ,"discriminant is zero"},
 {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
 {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
index b273007..e4c91ad 100644 (file)
@@ -673,6 +673,9 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, vo
 int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
                              char *kstr,int klen, pem_password_cb *cd, void *u);
 
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
 #endif /* SSLEAY_MACROS */
 
 
index 22793fa..9631ee2 100644 (file)
@@ -204,6 +204,20 @@ static int check_pem(const char *nm, const char *name)
                return 0;
                }
 
+       if(!strcmp(name,PEM_STRING_PARAMETERS))
+               {
+               int slen;
+               const EVP_PKEY_ASN1_METHOD *ameth;
+               slen = pem_check_suffix(nm, "PARAMETERS"); 
+               if (slen > 0)
+                       {
+                       ameth = EVP_PKEY_asn1_find_str(nm, slen);
+                       if (ameth && ameth->param_decode)
+                               return 1;
+                       }
+               return 0;
+               }
+
        /* Permit older strings */
 
        if(!strcmp(nm,PEM_STRING_X509_OLD) &&
index b9067e0..7747a05 100644 (file)
@@ -149,7 +149,7 @@ int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                pem_str,bp,(char *)x,enc,kstr,klen,cb,u);
        }
 
-EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
        {
        char *nm=NULL;
        const unsigned char *p=NULL;
@@ -159,7 +159,7 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
        EVP_PKEY *ret=NULL;
 
        if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
-                                                               bp, cb, u))
+                                                               bp, 0, NULL))
                return NULL;
        p = data;
 
@@ -192,7 +192,7 @@ err:
        return(ret);
        }
 
-int PEM_write_bio_Paramters(BIO *bp, EVP_PKEY *x)
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
        {
        char pem_str[80];
        if (!x->ameth || !x->ameth->param_encode)