From 2ca873e8d898e8a232ea707227400213980059a4 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 7 Dec 2011 12:44:03 +0000 Subject: [PATCH] transparently handle X9.42 DH parameters --- CHANGES | 5 +++++ apps/dhparam.c | 7 +++++- crypto/pem/pem.h | 2 ++ crypto/pem/pem_all.c | 2 +- crypto/pem/pem_err.c | 4 +++- crypto/pem/pem_lib.c | 3 +++ crypto/pem/pem_pkey.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 72 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 4a0ce55c56..ddf9059ef4 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,11 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] + *) Transparently support X9.42 DH parameters when calling + PEM_read_bio_DHparameters. This means existing applications can handle + the new parameter format automatically. + [Steve Henson] + *) Initial experimental support for X9.42 DH parameter format: mainly to support use of 'q' parameter for RFC5114 parameters. [Steve Henson] diff --git a/apps/dhparam.c b/apps/dhparam.c index b47097cbb2..79c0d64c51 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -513,7 +513,12 @@ bad: if (outformat == FORMAT_ASN1) i=i2d_DHparams_bio(out,dh); else if (outformat == FORMAT_PEM) - i=PEM_write_bio_DHparams(out,dh); + { + if (dh->q) + i=PEM_write_bio_DHxparams(out,dh); + else + i=PEM_write_bio_DHparams(out,dh); + } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h index e09ce80c4c..01dcde71d2 100644 --- a/crypto/pem/pem.h +++ b/crypto/pem/pem.h @@ -594,8 +594,10 @@ void ERR_load_PEM_strings(void); #define PEM_F_PEM_PK8PKEY 119 #define PEM_F_PEM_READ 108 #define PEM_F_PEM_READ_BIO 109 +#define PEM_F_PEM_READ_BIO_DHPARAMS 141 #define PEM_F_PEM_READ_BIO_PARAMETERS 140 #define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +#define PEM_F_PEM_READ_DHPARAMS 142 #define PEM_F_PEM_READ_PRIVATEKEY 124 #define PEM_F_PEM_SEALFINAL 110 #define PEM_F_PEM_SEALINIT 111 diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index e09b24ad7a..5c8c6f4158 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -289,7 +289,7 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, #ifndef OPENSSL_NO_DH -IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) +IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) #endif diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c index d644aeedd4..9690224f53 100644 --- a/crypto/pem/pem_err.c +++ b/crypto/pem/pem_err.c @@ -1,6 +1,6 @@ /* crypto/pem/pem_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2011 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 @@ -98,8 +98,10 @@ static ERR_STRING_DATA PEM_str_functs[]= {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, +{ERR_FUNC(PEM_F_PEM_READ_BIO_DHPARAMS), "PEM_READ_BIO_DHPARAMS"}, {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"}, {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, +{ERR_FUNC(PEM_F_PEM_READ_DHPARAMS), "PEM_READ_DHPARAMS"}, {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"}, diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 5a421fc4b6..9e551d1795 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -236,6 +236,9 @@ static int check_pem(const char *nm, const char *name) } return 0; } + /* If reading DH parameters handle X9.42 DH format too */ + if(!strcmp(nm,PEM_STRING_DHXPARAMS) && + !strcmp(name,PEM_STRING_DHPARAMS)) return 1; /* Permit older strings */ diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 8ecf24903b..e9e41dd4e8 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -68,6 +68,9 @@ #ifndef OPENSSL_NO_ENGINE #include #endif +#ifndef OPENSSL_NO_DH +#include +#endif #include "asn1_locl.h" int pem_check_suffix(const char *pem_str, const char *suffix); @@ -240,3 +243,52 @@ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, } #endif + +#ifndef OPENSSL_NO_DH + +/* Transparently read in PKCS#3 or X9.42 DH parameters */ + +DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) + { + char *nm=NULL; + const unsigned char *p=NULL; + unsigned char *data=NULL; + long len; + DH *ret=NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, + bp, cb, u)) + return NULL; + p = data; + + if (!strcmp(nm, PEM_STRING_DHXPARAMS)) + ret = d2i_DHxparams(x, &p, len); + else + ret = d2i_DHparams(x, &p, len); + + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS,ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return ret; + } + +#ifndef OPENSSL_NO_FP_API +DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) + { + BIO *b; + DH *ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + PEMerr(PEM_F_PEM_READ_DHPARAMS,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=PEM_read_bio_DHparams(b,x,cb,u); + BIO_free(b); + return(ret); + } +#endif + +#endif -- 2.25.1