From 31392c89d1135cf2a416f97295f6d21681b3fbc4 Mon Sep 17 00:00:00 2001 From: markus <> Date: Thu, 12 Sep 2002 20:53:05 +0000 Subject: import openssl-0.9.7-stable-SNAP-20020911 (without idea) --- src/lib/libcrypto/asn1/a_bitstr.c | 6 + src/lib/libcrypto/asn1/a_strex.c | 4 +- src/lib/libcrypto/asn1/asn1_lib.c | 9 +- src/lib/libcrypto/asn1/t_req.c | 260 ++++++----- src/lib/libcrypto/asn1/tasn_dec.c | 6 +- src/lib/libcrypto/bio/b_print.c | 2 +- src/lib/libcrypto/bn/bn.h | 2 +- src/lib/libcrypto/cryptlib.c | 8 - src/lib/libcrypto/cryptlib.h | 4 - src/lib/libcrypto/des/ecb_enc.c | 1 + src/lib/libcrypto/des/set_key.c | 2 +- src/lib/libcrypto/doc/DH_set_method.pod | 102 ++-- src/lib/libcrypto/doc/DSA_dup_DH.pod | 2 +- src/lib/libcrypto/doc/DSA_new.pod | 3 +- src/lib/libcrypto/doc/DSA_set_method.pod | 91 ++-- src/lib/libcrypto/doc/DSA_size.pod | 2 +- src/lib/libcrypto/doc/EVP_SealInit.pod | 2 + src/lib/libcrypto/doc/RAND_set_rand_method.pod | 44 +- src/lib/libcrypto/doc/RSA_new.pod | 6 +- src/lib/libcrypto/doc/RSA_set_method.pod | 127 +++-- src/lib/libcrypto/doc/RSA_size.pod | 2 +- src/lib/libcrypto/doc/dh.pod | 31 +- src/lib/libcrypto/doc/dsa.pod | 41 +- src/lib/libcrypto/doc/engine.pod | 621 +++++++++++++++++++++++++ src/lib/libcrypto/doc/evp.pod | 10 +- src/lib/libcrypto/doc/rsa.pod | 31 +- src/lib/libcrypto/evp/evp_locl.h | 12 +- src/lib/libcrypto/objects/obj_dat.c | 2 +- src/lib/libcrypto/pem/pem_lib.c | 7 +- src/lib/libcrypto/pkcs12/p12_asn.c | 6 +- src/lib/libcrypto/pkcs7/pk7_lib.c | 7 + src/lib/libcrypto/x509/x509.h | 2 + src/lib/libssl/doc/openssl.txt | 2 +- src/lib/libssl/s3_clnt.c | 12 +- src/lib/libssl/s3_srvr.c | 8 +- src/lib/libssl/ssl.h | 6 + src/lib/libssl/ssl_asn1.c | 5 +- src/lib/libssl/ssl_err.c | 6 + src/lib/libssl/ssl_lib.c | 17 +- src/lib/libssl/ssl_locl.h | 2 +- src/lib/libssl/ssl_sess.c | 7 +- 41 files changed, 1189 insertions(+), 331 deletions(-) create mode 100644 src/lib/libcrypto/doc/engine.pod (limited to 'src') diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c index ed0bdfbde1..e0265f69d2 100644 --- a/src/lib/libcrypto/asn1/a_bitstr.c +++ b/src/lib/libcrypto/asn1/a_bitstr.c @@ -120,6 +120,12 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, unsigned char *p,*s; int i; + if (len < 1) + { + i=ASN1_R_STRING_TOO_SHORT; + goto err; + } + if ((a == NULL) || ((*a) == NULL)) { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c index 8dab29dca1..7ddb7662f1 100644 --- a/src/lib/libcrypto/asn1/a_strex.c +++ b/src/lib/libcrypto/asn1/a_strex.c @@ -544,7 +544,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) { ASN1_STRING stmp, *str = &stmp; int mbflag, type, ret; - if(!*out || !in) return -1; + if(!in) return -1; type = in->type; if((type < 0) || (type > 30)) return -1; mbflag = tag2nbyte[type]; @@ -553,6 +553,6 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) stmp.data = NULL; ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); if(ret < 0) return ret; - if(out) *out = stmp.data; + *out = stmp.data; return stmp.length; } diff --git a/src/lib/libcrypto/asn1/asn1_lib.c b/src/lib/libcrypto/asn1/asn1_lib.c index 422685a3b4..0638870ab7 100644 --- a/src/lib/libcrypto/asn1/asn1_lib.c +++ b/src/lib/libcrypto/asn1/asn1_lib.c @@ -57,6 +57,7 @@ */ #include +#include #include "cryptlib.h" #include #include @@ -124,7 +125,7 @@ int ASN1_get_object(unsigned char **pp, long *plength, int *ptag, int *pclass, (int)(omax+ *pp)); #endif - if (*plength > (omax - (*pp - p))) + if (*plength > (omax - (p - *pp))) { ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG); /* Set this so that even if things are not long enough @@ -141,7 +142,7 @@ err: static int asn1_get_length(unsigned char **pp, int *inf, long *rl, int max) { unsigned char *p= *pp; - long ret=0; + unsigned long ret=0; int i; if (max-- < 1) return(0); @@ -170,10 +171,10 @@ static int asn1_get_length(unsigned char **pp, int *inf, long *rl, int max) else ret=i; } - if (ret < 0) + if (ret > LONG_MAX) return 0; *pp=p; - *rl=ret; + *rl=(long)ret; return(1); } diff --git a/src/lib/libcrypto/asn1/t_req.c b/src/lib/libcrypto/asn1/t_req.c index 848c29a2dd..739f272ecf 100644 --- a/src/lib/libcrypto/asn1/t_req.c +++ b/src/lib/libcrypto/asn1/t_req.c @@ -82,7 +82,7 @@ int X509_REQ_print_fp(FILE *fp, X509_REQ *x) } #endif -int X509_REQ_print(BIO *bp, X509_REQ *x) +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { unsigned long l; int i; @@ -92,143 +92,185 @@ int X509_REQ_print(BIO *bp, X509_REQ *x) STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(X509_EXTENSION) *exts; char str[128]; + char mlch = ' '; + int nmindent = 0; + + if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if(nmflags == X509_FLAG_COMPAT) + nmindent = 16; + ri=x->req_info; - sprintf(str,"Certificate Request:\n"); - if (BIO_puts(bp,str) <= 0) goto err; - sprintf(str,"%4sData:\n",""); - if (BIO_puts(bp,str) <= 0) goto err; - - neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":""; - l=0; - for (i=0; iversion->length; i++) - { l<<=8; l+=ri->version->data[i]; } - sprintf(str,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,l); - if (BIO_puts(bp,str) <= 0) goto err; - sprintf(str,"%8sSubject: ",""); - if (BIO_puts(bp,str) <= 0) goto err; - - X509_NAME_print(bp,ri->subject,16); - sprintf(str,"\n%8sSubject Public Key Info:\n",""); - if (BIO_puts(bp,str) <= 0) goto err; - i=OBJ_obj2nid(ri->pubkey->algor->algorithm); - sprintf(str,"%12sPublic Key Algorithm: %s\n","", - (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); - if (BIO_puts(bp,str) <= 0) goto err; - - pkey=X509_REQ_get_pubkey(x); -#ifndef OPENSSL_NO_RSA - if (pkey != NULL && pkey->type == EVP_PKEY_RSA) + if(!(cflag & X509_FLAG_NO_HEADER)) { - BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","", - BN_num_bits(pkey->pkey.rsa->n)); - RSA_print(bp,pkey->pkey.rsa,16); + if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err; + if (BIO_write(bp," Data:\n",10) <= 0) goto err; } - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey != NULL && pkey->type == EVP_PKEY_DSA) + if(!(cflag & X509_FLAG_NO_VERSION)) { - BIO_printf(bp,"%12sDSA Public Key:\n",""); - DSA_print(bp,pkey->pkey.dsa,16); + neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":""; + l=0; + for (i=0; iversion->length; i++) + { l<<=8; l+=ri->version->data[i]; } + sprintf(str,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,l); + if (BIO_puts(bp,str) <= 0) goto err; } - else -#endif - BIO_printf(bp,"%12sUnknown Public Key:\n",""); + if(!(cflag & X509_FLAG_NO_SUBJECT)) + { + if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err; + if (X509_NAME_print_ex(bp,ri->subject,nmindent, nmflags) < 0) goto err; + if (BIO_write(bp,"\n",1) <= 0) goto err; + } + if(!(cflag & X509_FLAG_NO_PUBKEY)) + { + if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0) + goto err; + if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; - if (pkey != NULL) - EVP_PKEY_free(pkey); + pkey=X509_REQ_get_pubkey(x); + if (pkey == NULL) + { + BIO_printf(bp,"%12sUnable to load Public Key\n",""); + ERR_print_errors(bp); + } + else +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) + { + BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","", + BN_num_bits(pkey->pkey.rsa->n)); + RSA_print(bp,pkey->pkey.rsa,16); + } + else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) + { + BIO_printf(bp,"%12sDSA Public Key:\n",""); + DSA_print(bp,pkey->pkey.dsa,16); + } + else +#endif + BIO_printf(bp,"%12sUnknown Public Key:\n",""); - /* may not be */ - sprintf(str,"%8sAttributes:\n",""); - if (BIO_puts(bp,str) <= 0) goto err; + EVP_PKEY_free(pkey); + } - sk=x->req_info->attributes; - if (sk_X509_ATTRIBUTE_num(sk) == 0) + if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) { - sprintf(str,"%12sa0:00\n",""); + /* may not be */ + sprintf(str,"%8sAttributes:\n",""); if (BIO_puts(bp,str) <= 0) goto err; - } - else - { - for (i=0; ireq_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { - ASN1_TYPE *at; - X509_ATTRIBUTE *a; - ASN1_BIT_STRING *bs=NULL; - ASN1_TYPE *t; - int j,type=0,count=1,ii=0; - - a=sk_X509_ATTRIBUTE_value(sk,i); - if(X509_REQ_extension_nid(OBJ_obj2nid(a->object))) - continue; - sprintf(str,"%12s",""); + sprintf(str,"%12sa0:00\n",""); if (BIO_puts(bp,str) <= 0) goto err; - if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0) + } + else { - if (a->single) + for (i=0; ivalue.single; - type=t->type; - bs=t->value.bit_string; - } - else + ASN1_TYPE *at; + X509_ATTRIBUTE *a; + ASN1_BIT_STRING *bs=NULL; + ASN1_TYPE *t; + int j,type=0,count=1,ii=0; + + a=sk_X509_ATTRIBUTE_value(sk,i); + if(X509_REQ_extension_nid(OBJ_obj2nid(a->object))) + continue; + sprintf(str,"%12s",""); + if (BIO_puts(bp,str) <= 0) goto err; + if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0) { - ii=0; - count=sk_ASN1_TYPE_num(a->value.set); + if (a->single) + { + t=a->value.single; + type=t->type; + bs=t->value.bit_string; + } + else + { + ii=0; + count=sk_ASN1_TYPE_num(a->value.set); get_next: - at=sk_ASN1_TYPE_value(a->value.set,ii); - type=at->type; - bs=at->value.asn1_string; + at=sk_ASN1_TYPE_value(a->value.set,ii); + type=at->type; + bs=at->value.asn1_string; + } + } + for (j=25-j; j>0; j--) + if (BIO_write(bp," ",1) != 1) goto err; + if (BIO_puts(bp,":") <= 0) goto err; + if ( (type == V_ASN1_PRINTABLESTRING) || + (type == V_ASN1_T61STRING) || + (type == V_ASN1_IA5STRING)) + { + if (BIO_write(bp,(char *)bs->data,bs->length) + != bs->length) + goto err; + BIO_puts(bp,"\n"); + } + else + { + BIO_puts(bp,"unable to print attribute\n"); + } + if (++ii < count) goto get_next; } } - for (j=25-j; j>0; j--) - if (BIO_write(bp," ",1) != 1) goto err; - if (BIO_puts(bp,":") <= 0) goto err; - if ( (type == V_ASN1_PRINTABLESTRING) || - (type == V_ASN1_T61STRING) || - (type == V_ASN1_IA5STRING)) + } + if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) + { + exts = X509_REQ_get_extensions(x); + if(exts) + { + BIO_printf(bp,"%8sRequested Extensions:\n",""); + for (i=0; idata,bs->length) - != bs->length) + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + int j; + ex=sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bp,"%12s","") <= 0) goto err; + obj=X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp,obj); + j=X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0) goto err; - BIO_puts(bp,"\n"); - } - else - { - BIO_puts(bp,"unable to print attribute\n"); + if(!X509V3_EXT_print(bp, ex, 0, 16)) + { + BIO_printf(bp, "%16s", ""); + M_ASN1_OCTET_STRING_print(bp,ex->value); + } + if (BIO_write(bp,"\n",1) <= 0) goto err; } - if (++ii < count) goto get_next; + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } } - exts = X509_REQ_get_extensions(x); - if(exts) { - BIO_printf(bp,"%8sRequested Extensions:\n",""); - for (i=0; ivalue); - } - if (BIO_write(bp,"\n",1) <= 0) goto err; + if(!(cflag & X509_FLAG_NO_SIGDUMP)) + { + if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err; } - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - } - - if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err; return(1); err: X509err(X509_F_X509_REQ_PRINT,ERR_R_BUF_LIB); return(0); } + +int X509_REQ_print(BIO *bp, X509_REQ *x) + { + return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); + } diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 0fc1f421e2..f87c08793a 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c @@ -913,10 +913,10 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *i ctx->ptag = ptag; ctx->hdrlen = p - q; ctx->valid = 1; - /* If definite length, length + header can't exceed total - * amount of data available. + /* If definite length, and no error, length + + * header can't exceed total amount of data available. */ - if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { + if(!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); asn1_tlc_clear(ctx); return 0; diff --git a/src/lib/libcrypto/bio/b_print.c b/src/lib/libcrypto/bio/b_print.c index 3ce1290772..80c9cb69db 100644 --- a/src/lib/libcrypto/bio/b_print.c +++ b/src/lib/libcrypto/bio/b_print.c @@ -109,7 +109,7 @@ * o ... (for OpenSSL) */ -#if HAVE_LONG_DOUBLE +#ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h index 1eaf879553..b40682f831 100644 --- a/src/lib/libcrypto/bn/bn.h +++ b/src/lib/libcrypto/bn/bn.h @@ -430,7 +430,7 @@ int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, int BN_from_montgomery(BIGNUM *r,const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx); void BN_MONT_CTX_free(BN_MONT_CTX *mont); -int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx); +int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx); BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod); diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c index d301b376f7..612b3b93b4 100644 --- a/src/lib/libcrypto/cryptlib.c +++ b/src/lib/libcrypto/cryptlib.c @@ -492,11 +492,3 @@ BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, #endif #endif - -void OpenSSLDie(const char *file,int line,const char *assertion) - { - fprintf(stderr,"%s(%d): OpenSSL internal error, assertion failed: %s\n", - file,line,assertion); - abort(); - } - diff --git a/src/lib/libcrypto/cryptlib.h b/src/lib/libcrypto/cryptlib.h index 985a6d377c..88e4ae509f 100644 --- a/src/lib/libcrypto/cryptlib.h +++ b/src/lib/libcrypto/cryptlib.h @@ -93,10 +93,6 @@ extern "C" { #define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) #define HEX_SIZE(type) ((sizeof(type)*2) -/* die if we have to */ -void OpenSSLDie(const char *file,int line,const char *assertion); -#define die(e) ((e) ? (void)0 : OpenSSLDie(__FILE__, __LINE__, #e)) - #ifdef __cplusplus } #endif diff --git a/src/lib/libcrypto/des/ecb_enc.c b/src/lib/libcrypto/des/ecb_enc.c index 4650f2fa0f..1b70f68806 100644 --- a/src/lib/libcrypto/des/ecb_enc.c +++ b/src/lib/libcrypto/des/ecb_enc.c @@ -57,6 +57,7 @@ */ #include "des_locl.h" +#include "des_ver.h" #include "spr.h" #include diff --git a/src/lib/libcrypto/des/set_key.c b/src/lib/libcrypto/des/set_key.c index 683916e71b..143008ed9c 100644 --- a/src/lib/libcrypto/des/set_key.c +++ b/src/lib/libcrypto/des/set_key.c @@ -342,7 +342,7 @@ void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) register DES_LONG *k; register int i; -#if OPENBSD_DEV_CRYPTO +#ifdef OPENBSD_DEV_CRYPTO memcpy(schedule->key,key,sizeof schedule->key); schedule->session=NULL; #endif diff --git a/src/lib/libcrypto/doc/DH_set_method.pod b/src/lib/libcrypto/doc/DH_set_method.pod index d990bf8786..73261fc467 100644 --- a/src/lib/libcrypto/doc/DH_set_method.pod +++ b/src/lib/libcrypto/doc/DH_set_method.pod @@ -2,7 +2,7 @@ =head1 NAME -DH_set_default_openssl_method, DH_get_default_openssl_method, +DH_set_default_method, DH_get_default_method, DH_set_method, DH_new_method, DH_OpenSSL - select DH method =head1 SYNOPSIS @@ -10,45 +10,47 @@ DH_set_method, DH_new_method, DH_OpenSSL - select DH method #include #include - void DH_set_default_openssl_method(DH_METHOD *meth); + void DH_set_default_method(const DH_METHOD *meth); - DH_METHOD *DH_get_default_openssl_method(void); + const DH_METHOD *DH_get_default_method(void); - int DH_set_method(DH *dh, ENGINE *engine); + int DH_set_method(DH *dh, const DH_METHOD *meth); DH *DH_new_method(ENGINE *engine); - DH_METHOD *DH_OpenSSL(void); + const DH_METHOD *DH_OpenSSL(void); =head1 DESCRIPTION A B specifies the functions that OpenSSL uses for Diffie-Hellman operations. By modifying the method, alternative implementations -such as hardware accelerators may be used. - -Initially, the default is to use the OpenSSL internal implementation. -DH_OpenSSL() returns a pointer to that method. - -DH_set_default_openssl_method() makes B the default method for all DH -structures created later. B This is true only whilst the default engine -for Diffie-Hellman operations remains as "openssl". ENGINEs provide an -encapsulation for implementations of one or more algorithms, and all the DH -functions mentioned here operate within the scope of the default -"openssl" engine. - -DH_get_default_openssl_method() returns a pointer to the current default -method for the "openssl" engine. - -DH_set_method() selects B as the engine that will be responsible for -all operations using the structure B. If this function completes successfully, -then the B structure will have its own functional reference of B, so -the caller should remember to free their own reference to B when they are -finished with it. NB: An ENGINE's DH_METHOD can be retrieved (or set) by -ENGINE_get_DH() or ENGINE_set_DH(). - -DH_new_method() allocates and initializes a DH structure so that -B will be used for the DH operations. If B is NULL, -the default engine for Diffie-Hellman opertaions is used. +such as hardware accelerators may be used. IMPORTANT: See the NOTES section for +important information about how these DH API functions are affected by the use +of B API calls. + +Initially, the default DH_METHOD is the OpenSSL internal implementation, as +returned by DH_OpenSSL(). + +DH_set_default_method() makes B the default method for all DH +structures created later. B: This is true only whilst no ENGINE has been set +as a default for DH, so this function is no longer recommended. + +DH_get_default_method() returns a pointer to the current default DH_METHOD. +However, the meaningfulness of this result is dependant on whether the ENGINE +API is being used, so this function is no longer recommended. + +DH_set_method() selects B to perform all operations using the key B. +This will replace the DH_METHOD used by the DH key and if the previous method +was supplied by an ENGINE, the handle to that ENGINE will be released during the +change. It is possible to have DH keys that only work with certain DH_METHOD +implementations (eg. from an ENGINE module that supports embedded +hardware-protected keys), and in such cases attempting to change the DH_METHOD +for the key can have unexpected results. + +DH_new_method() allocates and initializes a DH structure so that B will +be used for the DH operations. If B is NULL, the default ENGINE for DH +operations is used, and if no default ENGINE is set, the DH_METHOD controlled by +DH_set_default_method() is used. =head1 THE DH_METHOD STRUCTURE @@ -82,17 +84,28 @@ the default engine for Diffie-Hellman opertaions is used. =head1 RETURN VALUES -DH_OpenSSL() and DH_get_default_openssl_method() return pointers to the -respective Bs. +DH_OpenSSL() and DH_get_default_method() return pointers to the respective +Bs. + +DH_set_default_method() returns no value. + +DH_set_method() returns non-zero if the provided B was successfully set as +the method for B (including unloading the ENGINE handle if the previous +method was supplied by an ENGINE). -DH_set_default_openssl_method() returns no value. +DH_new_method() returns NULL and sets an error code that can be obtained by +L if the allocation fails. Otherwise it +returns a pointer to the newly allocated structure. -DH_set_method() returns non-zero if the ENGINE associated with B -was successfully changed to B. +=head1 NOTES -DH_new_method() returns NULL and sets an error code that can be -obtained by L if the allocation fails. -Otherwise it returns a pointer to the newly allocated structure. +As of version 0.9.7, DH_METHOD implementations are grouped together with other +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B modules. If a +default ENGINE is specified for DH functionality using an ENGINE API function, +that will override any DH defaults set using the DH API (ie. +DH_set_default_method()). For this reason, the ENGINE API is the recommended way +to control default implementations for use in DH and other cryptographic +algorithms. =head1 SEE ALSO @@ -103,9 +116,14 @@ L, L DH_set_default_method(), DH_get_default_method(), DH_set_method(), DH_new_method() and DH_OpenSSL() were added in OpenSSL 0.9.4. -DH_set_default_openssl_method() and DH_get_default_openssl_method() -replaced DH_set_default_method() and DH_get_default_method() respectively, -and DH_set_method() and DH_new_method() were altered to use Bs -rather than Bs during development of OpenSSL 0.9.6. +DH_set_default_openssl_method() and DH_get_default_openssl_method() replaced +DH_set_default_method() and DH_get_default_method() respectively, and +DH_set_method() and DH_new_method() were altered to use Bs rather than +Bs during development of the engine version of OpenSSL 0.9.6. For +0.9.7, the handling of defaults in the ENGINE API was restructured so that this +change was reversed, and behaviour of the other functions resembled more closely +the previous behaviour. The behaviour of defaults in the ENGINE API now +transparently overrides the behaviour of defaults in the DH API without +requiring changing these function prototypes. =cut diff --git a/src/lib/libcrypto/doc/DSA_dup_DH.pod b/src/lib/libcrypto/doc/DSA_dup_DH.pod index 29cb1075d1..fdfe125ab0 100644 --- a/src/lib/libcrypto/doc/DSA_dup_DH.pod +++ b/src/lib/libcrypto/doc/DSA_dup_DH.pod @@ -8,7 +8,7 @@ DSA_dup_DH - create a DH structure out of DSA structure #include - DH * DSA_dup_DH(DSA *r); + DH * DSA_dup_DH(const DSA *r); =head1 DESCRIPTION diff --git a/src/lib/libcrypto/doc/DSA_new.pod b/src/lib/libcrypto/doc/DSA_new.pod index 7dde54445b..546146d9de 100644 --- a/src/lib/libcrypto/doc/DSA_new.pod +++ b/src/lib/libcrypto/doc/DSA_new.pod @@ -14,7 +14,8 @@ DSA_new, DSA_free - allocate and free DSA objects =head1 DESCRIPTION -DSA_new() allocates and initializes a B structure. +DSA_new() allocates and initializes a B structure. It is equivalent to +calling DSA_new_method(NULL). DSA_free() frees the B structure and its components. The values are erased before the memory is returned to the system. diff --git a/src/lib/libcrypto/doc/DSA_set_method.pod b/src/lib/libcrypto/doc/DSA_set_method.pod index 36a1052d27..bc3cfb1f0a 100644 --- a/src/lib/libcrypto/doc/DSA_set_method.pod +++ b/src/lib/libcrypto/doc/DSA_set_method.pod @@ -2,7 +2,7 @@ =head1 NAME -DSA_set_default_openssl_method, DSA_get_default_openssl_method, +DSA_set_default_method, DSA_get_default_method, DSA_set_method, DSA_new_method, DSA_OpenSSL - select DSA method =head1 SYNOPSIS @@ -10,11 +10,11 @@ DSA_set_method, DSA_new_method, DSA_OpenSSL - select DSA method #include #include - void DSA_set_default_openssl_method(DSA_METHOD *meth); + void DSA_set_default_method(const DSA_METHOD *meth); - DSA_METHOD *DSA_get_default_openssl_method(void); + const DSA_METHOD *DSA_get_default_method(void); - int DSA_set_method(DSA *dsa, ENGINE *engine); + int DSA_set_method(DSA *dsa, const DSA_METHOD *meth); DSA *DSA_new_method(ENGINE *engine); @@ -24,26 +24,35 @@ DSA_set_method, DSA_new_method, DSA_OpenSSL - select DSA method A B specifies the functions that OpenSSL uses for DSA operations. By modifying the method, alternative implementations -such as hardware accelerators may be used. - -Initially, the default is to use the OpenSSL internal implementation. -DSA_OpenSSL() returns a pointer to that method. - -DSA_set_default_openssl_method() makes B the default method for -all DSA structures created later. B This is true only whilst the -default engine for DSA operations remains as "openssl". ENGINEs -provide an encapsulation for implementations of one or more algorithms at a -time, and all the DSA functions mentioned here operate within the scope -of the default "openssl" engine. - -DSA_get_default_openssl_method() returns a pointer to the current default -method for the "openssl" engine. - -DSA_set_method() selects B for all operations using the structure B. - -DSA_new_method() allocates and initializes a DSA structure so that -B will be used for the DSA operations. If B is NULL, -the default engine for DSA operations is used. +such as hardware accelerators may be used. IMPORTANT: See the NOTES section for +important information about how these DSA API functions are affected by the use +of B API calls. + +Initially, the default DSA_METHOD is the OpenSSL internal implementation, +as returned by DSA_OpenSSL(). + +DSA_set_default_method() makes B the default method for all DSA +structures created later. B: This is true only whilst no ENGINE has +been set as a default for DSA, so this function is no longer recommended. + +DSA_get_default_method() returns a pointer to the current default +DSA_METHOD. However, the meaningfulness of this result is dependant on +whether the ENGINE API is being used, so this function is no longer +recommended. + +DSA_set_method() selects B to perform all operations using the key +B. This will replace the DSA_METHOD used by the DSA key and if the +previous method was supplied by an ENGINE, the handle to that ENGINE will +be released during the change. It is possible to have DSA keys that only +work with certain DSA_METHOD implementations (eg. from an ENGINE module +that supports embedded hardware-protected keys), and in such cases +attempting to change the DSA_METHOD for the key can have unexpected +results. + +DSA_new_method() allocates and initializes a DSA structure so that B +will be used for the DSA operations. If B is NULL, the default engine +for DSA operations is used, and if no default ENGINE is set, the DSA_METHOD +controlled by DSA_set_default_method() is used. =head1 THE DSA_METHOD STRUCTURE @@ -89,18 +98,29 @@ struct =head1 RETURN VALUES -DSA_OpenSSL() and DSA_get_default_openssl_method() return pointers to the -respective Bs. +DSA_OpenSSL() and DSA_get_default_method() return pointers to the respective +Bs. -DSA_set_default_openssl_method() returns no value. +DSA_set_default_method() returns no value. -DSA_set_method() returns non-zero if the ENGINE associated with B -was successfully changed to B. +DSA_set_method() returns non-zero if the provided B was successfully set as +the method for B (including unloading the ENGINE handle if the previous +method was supplied by an ENGINE). DSA_new_method() returns NULL and sets an error code that can be obtained by L if the allocation fails. Otherwise it returns a pointer to the newly allocated structure. +=head1 NOTES + +As of version 0.9.7, DSA_METHOD implementations are grouped together with other +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B modules. If a +default ENGINE is specified for DSA functionality using an ENGINE API function, +that will override any DSA defaults set using the DSA API (ie. +DSA_set_default_method()). For this reason, the ENGINE API is the recommended way +to control default implementations for use in DSA and other cryptographic +algorithms. + =head1 SEE ALSO L, L @@ -110,9 +130,14 @@ L, L DSA_set_default_method(), DSA_get_default_method(), DSA_set_method(), DSA_new_method() and DSA_OpenSSL() were added in OpenSSL 0.9.4. -DSA_set_default_openssl_method() and DSA_get_default_openssl_method() -replaced DSA_set_default_method() and DSA_get_default_method() respectively, -and DSA_set_method() and DSA_new_method() were altered to use Bs -rather than Bs during development of OpenSSL 0.9.6. +DSA_set_default_openssl_method() and DSA_get_default_openssl_method() replaced +DSA_set_default_method() and DSA_get_default_method() respectively, and +DSA_set_method() and DSA_new_method() were altered to use Bs rather than +Bs during development of the engine version of OpenSSL 0.9.6. For +0.9.7, the handling of defaults in the ENGINE API was restructured so that this +change was reversed, and behaviour of the other functions resembled more closely +the previous behaviour. The behaviour of defaults in the ENGINE API now +transparently overrides the behaviour of defaults in the DSA API without +requiring changing these function prototypes. =cut diff --git a/src/lib/libcrypto/doc/DSA_size.pod b/src/lib/libcrypto/doc/DSA_size.pod index 23b6320a4d..ba4f650361 100644 --- a/src/lib/libcrypto/doc/DSA_size.pod +++ b/src/lib/libcrypto/doc/DSA_size.pod @@ -8,7 +8,7 @@ DSA_size - get DSA signature size #include - int DSA_size(DSA *dsa); + int DSA_size(const DSA *dsa); =head1 DESCRIPTION diff --git a/src/lib/libcrypto/doc/EVP_SealInit.pod b/src/lib/libcrypto/doc/EVP_SealInit.pod index 0451eb648a..25ef07f7c7 100644 --- a/src/lib/libcrypto/doc/EVP_SealInit.pod +++ b/src/lib/libcrypto/doc/EVP_SealInit.pod @@ -73,4 +73,6 @@ L =head1 HISTORY +EVP_SealFinal() did not return a value before OpenSSL 0.9.7. + =cut diff --git a/src/lib/libcrypto/doc/RAND_set_rand_method.pod b/src/lib/libcrypto/doc/RAND_set_rand_method.pod index 464eba416d..c9bb6d9f27 100644 --- a/src/lib/libcrypto/doc/RAND_set_rand_method.pod +++ b/src/lib/libcrypto/doc/RAND_set_rand_method.pod @@ -8,22 +8,30 @@ RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - select RAND method #include - void RAND_set_rand_method(RAND_METHOD *meth); + void RAND_set_rand_method(const RAND_METHOD *meth); - RAND_METHOD *RAND_get_rand_method(void); + const RAND_METHOD *RAND_get_rand_method(void); RAND_METHOD *RAND_SSLeay(void); =head1 DESCRIPTION -A B specifies the functions that OpenSSL uses for random -number generation. By modifying the method, alternative -implementations such as hardware RNGs may be used. Initially, the -default is to use the OpenSSL internal implementation. RAND_SSLeay() -returns a pointer to that method. +A B specifies the functions that OpenSSL uses for random number +generation. By modifying the method, alternative implementations such as +hardware RNGs may be used. IMPORTANT: See the NOTES section for important +information about how these RAND API functions are affected by the use of +B API calls. -RAND_set_rand_method() sets the RAND method to B. -RAND_get_rand_method() returns a pointer to the current method. +Initially, the default RAND_METHOD is the OpenSSL internal implementation, as +returned by RAND_SSLeay(). + +RAND_set_default_method() makes B the method for PRNG use. B: This is +true only whilst no ENGINE has been set as a default for RAND, so this function +is no longer recommended. + +RAND_get_default_method() returns a pointer to the current RAND_METHOD. +However, the meaningfulness of this result is dependant on whether the ENGINE +API is being used, so this function is no longer recommended. =head1 THE RAND_METHOD STRUCTURE @@ -47,13 +55,29 @@ Each component may be NULL if the function is not implemented. RAND_set_rand_method() returns no value. RAND_get_rand_method() and RAND_SSLeay() return pointers to the respective methods. +=head1 NOTES + +As of version 0.9.7, RAND_METHOD implementations are grouped together with other +algorithmic APIs (eg. RSA_METHOD, EVP_CIPHER, etc) in B modules. If a +default ENGINE is specified for RAND functionality using an ENGINE API function, +that will override any RAND defaults set using the RAND API (ie. +RAND_set_rand_method()). For this reason, the ENGINE API is the recommended way +to control default implementations for use in RAND and other cryptographic +algorithms. + =head1 SEE ALSO -L +L, L =head1 HISTORY RAND_set_rand_method(), RAND_get_rand_method() and RAND_SSLeay() are available in all versions of OpenSSL. +In the engine version of version 0.9.6, RAND_set_rand_method() was altered to +take an ENGINE pointer as its argument. As of version 0.9.7, that has been +reverted as the ENGINE API transparently overrides RAND defaults if used, +otherwise RAND API functions work as before. RAND_set_rand_engine() was also +introduced in version 0.9.7. + =cut diff --git a/src/lib/libcrypto/doc/RSA_new.pod b/src/lib/libcrypto/doc/RSA_new.pod index f16490ea6a..f0d996c40f 100644 --- a/src/lib/libcrypto/doc/RSA_new.pod +++ b/src/lib/libcrypto/doc/RSA_new.pod @@ -14,7 +14,8 @@ RSA_new, RSA_free - allocate and free RSA objects =head1 DESCRIPTION -RSA_new() allocates and initializes an B structure. +RSA_new() allocates and initializes an B structure. It is equivalent to +calling RSA_new_method(NULL). RSA_free() frees the B structure and its components. The key is erased before the memory is returned to the system. @@ -29,7 +30,8 @@ RSA_free() returns no value. =head1 SEE ALSO -L, L, L +L, L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_set_method.pod b/src/lib/libcrypto/doc/RSA_set_method.pod index 14917dd35f..0687c2242a 100644 --- a/src/lib/libcrypto/doc/RSA_set_method.pod +++ b/src/lib/libcrypto/doc/RSA_set_method.pod @@ -11,52 +11,64 @@ RSA_null_method, RSA_flags, RSA_new_method - select RSA method #include #include - void RSA_set_default_openssl_method(RSA_METHOD *meth); + void RSA_set_default_method(const RSA_METHOD *meth); - RSA_METHOD *RSA_get_default_openssl_method(void); + RSA_METHOD *RSA_get_default_method(void); - int RSA_set_method(RSA *rsa, ENGINE *engine); + int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); - RSA_METHOD *RSA_get_method(RSA *rsa); + RSA_METHOD *RSA_get_method(const RSA *rsa); RSA_METHOD *RSA_PKCS1_SSLeay(void); RSA_METHOD *RSA_null_method(void); - int RSA_flags(RSA *rsa); + int RSA_flags(const RSA *rsa); RSA *RSA_new_method(ENGINE *engine); =head1 DESCRIPTION An B specifies the functions that OpenSSL uses for RSA -operations. By modifying the method, alternative implementations -such as hardware accelerators may be used. - -Initially, the default is to use the OpenSSL internal implementation. -RSA_PKCS1_SSLeay() returns a pointer to that method. - -RSA_set_default_openssl_method() makes B the default method for all B -structures created later. B This is true only whilst the default engine -for RSA operations remains as "openssl". ENGINEs provide an -encapsulation for implementations of one or more algorithms at a time, and all -the RSA functions mentioned here operate within the scope of the default -"openssl" engine. - -RSA_get_default_openssl_method() returns a pointer to the current default -method for the "openssl" engine. - -RSA_set_method() selects B for all operations using the key -B. - -RSA_get_method() returns a pointer to the RSA_METHOD from the currently -selected ENGINE for B. - -RSA_flags() returns the B that are set for B's current method. +operations. By modifying the method, alternative implementations such as +hardware accelerators may be used. IMPORTANT: See the NOTES section for +important information about how these RSA API functions are affected by the +use of B API calls. + +Initially, the default RSA_METHOD is the OpenSSL internal implementation, +as returned by RSA_PKCS1_SSLeay(). + +RSA_set_default_method() makes B the default method for all RSA +structures created later. B: This is true only whilst no ENGINE has +been set as a default for RSA, so this function is no longer recommended. + +RSA_get_default_method() returns a pointer to the current default +RSA_METHOD. However, the meaningfulness of this result is dependant on +whether the ENGINE API is being used, so this function is no longer +recommended. + +RSA_set_method() selects B to perform all operations using the key +B. This will replace the RSA_METHOD used by the RSA key and if the +previous method was supplied by an ENGINE, the handle to that ENGINE will +be released during the change. It is possible to have RSA keys that only +work with certain RSA_METHOD implementations (eg. from an ENGINE module +that supports embedded hardware-protected keys), and in such cases +attempting to change the RSA_METHOD for the key can have unexpected +results. + +RSA_get_method() returns a pointer to the RSA_METHOD being used by B. +This method may or may not be supplied by an ENGINE implementation, but if +it is, the return value can only be guaranteed to be valid as long as the +RSA key itself is valid and does not have its implementation changed by +RSA_set_method(). + +RSA_flags() returns the B that are set for B's current +RSA_METHOD. See the BUGS section. RSA_new_method() allocates and initializes an RSA structure so that -B will be used for the RSA operations. If B is NULL, -the default engine for RSA operations is used. +B will be used for the RSA operations. If B is NULL, the +default ENGINE for RSA operations is used, and if no default ENGINE is set, +the RSA_METHOD controlled by RSA_set_default_method() is used. =head1 THE RSA_METHOD STRUCTURE @@ -121,22 +133,45 @@ the default engine for RSA operations is used. =head1 RETURN VALUES -RSA_PKCS1_SSLeay(), RSA_PKCS1_null_method(), RSA_get_default_openssl_method() +RSA_PKCS1_SSLeay(), RSA_PKCS1_null_method(), RSA_get_default_method() and RSA_get_method() return pointers to the respective RSA_METHODs. -RSA_set_default_openssl_method() returns no value. +RSA_set_default_method() returns no value. -RSA_set_method() selects B as the engine that will be responsible for -all operations using the structure B. If this function completes successfully, -then the B structure will have its own functional reference of B, so -the caller should remember to free their own reference to B when they are -finished with it. NB: An ENGINE's RSA_METHOD can be retrieved (or set) by -ENGINE_get_RSA() or ENGINE_set_RSA(). +RSA_set_method() returns a pointer to the old RSA_METHOD implementation +that was replaced. However, this return value should probably be ignored +because if it was supplied by an ENGINE, the pointer could be invalidated +at any time if the ENGINE is unloaded (in fact it could be unloaded as a +result of the RSA_set_method() function releasing its handle to the +ENGINE). For this reason, the return type may be replaced with a B +declaration in a future release. -RSA_new_method() returns NULL and sets an error code that can be -obtained by L if the allocation fails. Otherwise +RSA_new_method() returns NULL and sets an error code that can be obtained +by L if the allocation fails. Otherwise it returns a pointer to the newly allocated structure. +=head1 NOTES + +As of version 0.9.7, RSA_METHOD implementations are grouped together with +other algorithmic APIs (eg. DSA_METHOD, EVP_CIPHER, etc) into B +modules. If a default ENGINE is specified for RSA functionality using an +ENGINE API function, that will override any RSA defaults set using the RSA +API (ie. RSA_set_default_method()). For this reason, the ENGINE API is the +recommended way to control default implementations for use in RSA and other +cryptographic algorithms. + +=head1 BUGS + +The behaviour of RSA_flags() is a mis-feature that is left as-is for now +to avoid creating compatibility problems. RSA functionality, such as the +encryption functions, are controlled by the B value in the RSA key +itself, not by the B value in the RSA_METHOD attached to the RSA key +(which is what this function returns). If the flags element of an RSA key +is changed, the changes will be honoured by RSA functionality but will not +be reflected in the return value of the RSA_flags() function - in effect +RSA_flags() behaves more like an RSA_default_flags() function (which does +not currently exist). + =head1 SEE ALSO L, L @@ -149,8 +184,14 @@ well as the rsa_sign and rsa_verify components of RSA_METHOD were added in OpenSSL 0.9.4. RSA_set_default_openssl_method() and RSA_get_default_openssl_method() -replaced RSA_set_default_method() and RSA_get_default_method() respectively, -and RSA_set_method() and RSA_new_method() were altered to use Bs -rather than Bs during development of OpenSSL 0.9.6. +replaced RSA_set_default_method() and RSA_get_default_method() +respectively, and RSA_set_method() and RSA_new_method() were altered to use +Bs rather than Bs during development of the engine +version of OpenSSL 0.9.6. For 0.9.7, the handling of defaults in the ENGINE +API was restructured so that this change was reversed, and behaviour of the +other functions resembled more closely the previous behaviour. The +behaviour of defaults in the ENGINE API now transparently overrides the +behaviour of defaults in the RSA API without requiring changing these +function prototypes. =cut diff --git a/src/lib/libcrypto/doc/RSA_size.pod b/src/lib/libcrypto/doc/RSA_size.pod index b36b4d58d5..5b7f835f95 100644 --- a/src/lib/libcrypto/doc/RSA_size.pod +++ b/src/lib/libcrypto/doc/RSA_size.pod @@ -8,7 +8,7 @@ RSA_size - get RSA modulus size #include - int RSA_size(RSA *rsa); + int RSA_size(const RSA *rsa); =head1 DESCRIPTION diff --git a/src/lib/libcrypto/doc/dh.pod b/src/lib/libcrypto/doc/dh.pod index b4be4be405..c3ccd06207 100644 --- a/src/lib/libcrypto/doc/dh.pod +++ b/src/lib/libcrypto/doc/dh.pod @@ -12,20 +12,20 @@ dh - Diffie-Hellman key agreement DH * DH_new(void); void DH_free(DH *dh); - int DH_size(DH *dh); + int DH_size(const DH *dh); DH * DH_generate_parameters(int prime_len, int generator, void (*callback)(int, int, void *), void *cb_arg); - int DH_check(DH *dh, int *codes); + int DH_check(const DH *dh, int *codes); int DH_generate_key(DH *dh); int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh); - void DH_set_default_openssl_method(DH_METHOD *meth); - DH_METHOD *DH_get_default_openssl_method(void); - int DH_set_method(DH *dh, ENGINE *engine); + void DH_set_default_method(const DH_METHOD *meth); + const DH_METHOD *DH_get_default_method(void); + int DH_set_method(DH *dh, const DH_METHOD *meth); DH *DH_new_method(ENGINE *engine); - DH_METHOD *DH_OpenSSL(void); + const DH_METHOD *DH_OpenSSL(void); int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(), int (*dup_func)(), void (*free_func)()); @@ -33,10 +33,10 @@ dh - Diffie-Hellman key agreement char *DH_get_ex_data(DH *d, int idx); DH * d2i_DHparams(DH **a, unsigned char **pp, long length); - int i2d_DHparams(DH *a, unsigned char **pp); + int i2d_DHparams(const DH *a, unsigned char **pp); - int DHparams_print_fp(FILE *fp, DH *x); - int DHparams_print(BIO *bp, DH *x); + int DHparams_print_fp(FILE *fp, const DH *x); + int DHparams_print(BIO *bp, const DH *x); =head1 DESCRIPTION @@ -57,11 +57,20 @@ The B structure consists of several BIGNUM components. }; DH +Note that DH keys may use non-standard B implementations, +either directly or by the use of B modules. In some cases (eg. an +ENGINE providing support for hardware-embedded keys), these BIGNUM values +will not be used by the implementation or may be used for alternative data +storage. For this reason, applications should generally avoid using DH +structure elements directly and instead use API functions to query or +modify keys. + =head1 SEE ALSO L, L, L, L, -L, L, L, -L, L, +L, L, L, +L, L, +L, L, L, L, L diff --git a/src/lib/libcrypto/doc/dsa.pod b/src/lib/libcrypto/doc/dsa.pod index 82d7fb77cd..da07d2b930 100644 --- a/src/lib/libcrypto/doc/dsa.pod +++ b/src/lib/libcrypto/doc/dsa.pod @@ -12,13 +12,13 @@ dsa - Digital Signature Algorithm DSA * DSA_new(void); void DSA_free(DSA *dsa); - int DSA_size(DSA *dsa); + int DSA_size(const DSA *dsa); DSA * DSA_generate_parameters(int bits, unsigned char *seed, int seed_len, int *counter_ret, unsigned long *h_ret, void (*callback)(int, int, void *), void *cb_arg); - DH * DSA_dup_DH(DSA *r); + DH * DSA_dup_DH(const DSA *r); int DSA_generate_key(DSA *dsa); @@ -27,13 +27,13 @@ dsa - Digital Signature Algorithm int DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp, BIGNUM **rp); int DSA_verify(int dummy, const unsigned char *dgst, int len, - unsigned char *sigbuf, int siglen, DSA *dsa); + const unsigned char *sigbuf, int siglen, DSA *dsa); - void DSA_set_default_openssl_method(DSA_METHOD *meth); - DSA_METHOD *DSA_get_default_openssl_method(void); - int DSA_set_method(DSA *dsa, ENGINE *engine); + void DSA_set_default_method(const DSA_METHOD *meth); + const DSA_METHOD *DSA_get_default_method(void); + int DSA_set_method(DSA *dsa, const DSA_METHOD *meth); DSA *DSA_new_method(ENGINE *engine); - DSA_METHOD *DSA_OpenSSL(void); + const DSA_METHOD *DSA_OpenSSL(void); int DSA_get_ex_new_index(long argl, char *argp, int (*new_func)(), int (*dup_func)(), void (*free_func)()); @@ -42,7 +42,7 @@ dsa - Digital Signature Algorithm DSA_SIG *DSA_SIG_new(void); void DSA_SIG_free(DSA_SIG *a); - int i2d_DSA_SIG(DSA_SIG *a, unsigned char **pp); + int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length); DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); @@ -52,14 +52,14 @@ dsa - Digital Signature Algorithm DSA * d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length); DSA * d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); DSA * d2i_DSAparams(DSA **a, unsigned char **pp, long length); - int i2d_DSAPublicKey(DSA *a, unsigned char **pp); - int i2d_DSAPrivateKey(DSA *a, unsigned char **pp); - int i2d_DSAparams(DSA *a,unsigned char **pp); + int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); + int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); + int i2d_DSAparams(const DSA *a,unsigned char **pp); - int DSAparams_print(BIO *bp, DSA *x); - int DSAparams_print_fp(FILE *fp, DSA *x); - int DSA_print(BIO *bp, DSA *x, int off); - int DSA_print_fp(FILE *bp, DSA *x, int off); + int DSAparams_print(BIO *bp, const DSA *x); + int DSAparams_print_fp(FILE *fp, const DSA *x); + int DSA_print(BIO *bp, const DSA *x, int off); + int DSA_print_fp(FILE *bp, const DSA *x, int off); =head1 DESCRIPTION @@ -85,6 +85,14 @@ The B structure consists of several BIGNUM components. In public keys, B is NULL. +Note that DSA keys may use non-standard B implementations, +either directly or by the use of B modules. In some cases (eg. an +ENGINE providing support for hardware-embedded keys), these BIGNUM values +will not be used by the implementation or may be used for alternative data +storage. For this reason, applications should generally avoid using DSA +structure elements directly and instead use API functions to query or +modify keys. + =head1 CONFORMING TO US Federal Information Processing Standard FIPS 186 (Digital Signature @@ -93,7 +101,8 @@ Standard, DSS), ANSI X9.30 =head1 SEE ALSO L, L, L, L, -L, L, L, +L, L, L, +L, L, L, L, diff --git a/src/lib/libcrypto/doc/engine.pod b/src/lib/libcrypto/doc/engine.pod new file mode 100644 index 0000000000..61e0264bb7 --- /dev/null +++ b/src/lib/libcrypto/doc/engine.pod @@ -0,0 +1,621 @@ +=pod + +=head1 NAME + +engine - ENGINE cryptographic module support + +=head1 SYNOPSIS + + #include + + ENGINE *ENGINE_get_first(void); + ENGINE *ENGINE_get_last(void); + ENGINE *ENGINE_get_next(ENGINE *e); + ENGINE *ENGINE_get_prev(ENGINE *e); + + int ENGINE_add(ENGINE *e); + int ENGINE_remove(ENGINE *e); + + ENGINE *ENGINE_by_id(const char *id); + + int ENGINE_init(ENGINE *e); + int ENGINE_finish(ENGINE *e); + + void ENGINE_load_openssl(void); + void ENGINE_load_dynamic(void); + void ENGINE_load_cswift(void); + void ENGINE_load_chil(void); + void ENGINE_load_atalla(void); + void ENGINE_load_nuron(void); + void ENGINE_load_ubsec(void); + void ENGINE_load_aep(void); + void ENGINE_load_sureware(void); + void ENGINE_load_4758cca(void); + void ENGINE_load_openbsd_dev_crypto(void); + void ENGINE_load_builtin_engines(void); + + void ENGINE_cleanup(void); + + ENGINE *ENGINE_get_default_RSA(void); + ENGINE *ENGINE_get_default_DSA(void); + ENGINE *ENGINE_get_default_DH(void); + ENGINE *ENGINE_get_default_RAND(void); + ENGINE *ENGINE_get_cipher_engine(int nid); + ENGINE *ENGINE_get_digest_engine(int nid); + + int ENGINE_set_default_RSA(ENGINE *e); + int ENGINE_set_default_DSA(ENGINE *e); + int ENGINE_set_default_DH(ENGINE *e); + int ENGINE_set_default_RAND(ENGINE *e); + int ENGINE_set_default_ciphers(ENGINE *e); + int ENGINE_set_default_digests(ENGINE *e); + int ENGINE_set_default_string(ENGINE *e, const char *list); + + int ENGINE_set_default(ENGINE *e, unsigned int flags); + + unsigned int ENGINE_get_table_flags(void); + void ENGINE_set_table_flags(unsigned int flags); + + int ENGINE_register_RSA(ENGINE *e); + void ENGINE_unregister_RSA(ENGINE *e); + void ENGINE_register_all_RSA(void); + int ENGINE_register_DSA(ENGINE *e); + void ENGINE_unregister_DSA(ENGINE *e); + void ENGINE_register_all_DSA(void); + int ENGINE_register_DH(ENGINE *e); + void ENGINE_unregister_DH(ENGINE *e); + void ENGINE_register_all_DH(void); + int ENGINE_register_RAND(ENGINE *e); + void ENGINE_unregister_RAND(ENGINE *e); + void ENGINE_register_all_RAND(void); + int ENGINE_register_ciphers(ENGINE *e); + void ENGINE_unregister_ciphers(ENGINE *e); + void ENGINE_register_all_ciphers(void); + int ENGINE_register_digests(ENGINE *e); + void ENGINE_unregister_digests(ENGINE *e); + void ENGINE_register_all_digests(void); + int ENGINE_register_complete(ENGINE *e); + int ENGINE_register_all_complete(void); + + int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); + int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(), int cmd_optional); + int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + + int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); + void *ENGINE_get_ex_data(const ENGINE *e, int idx); + + int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + + ENGINE *ENGINE_new(void); + int ENGINE_free(ENGINE *e); + + int ENGINE_set_id(ENGINE *e, const char *id); + int ENGINE_set_name(ENGINE *e, const char *name); + int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); + int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); + int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); + int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); + int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); + int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); + int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); + int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); + int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); + int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); + int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); + int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); + int ENGINE_set_flags(ENGINE *e, int flags); + int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); + + const char *ENGINE_get_id(const ENGINE *e); + const char *ENGINE_get_name(const ENGINE *e); + const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); + const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); + const DH_METHOD *ENGINE_get_DH(const ENGINE *e); + const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); + ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); + ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); + ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); + ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); + ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); + ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); + const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); + const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); + int ENGINE_get_flags(const ENGINE *e); + const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); + + EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); + EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); + + void ENGINE_add_conf_module(void); + +=head1 DESCRIPTION + +These functions create, manipulate, and use cryptographic modules in the +form of B objects. These objects act as containers for +implementations of cryptographic algorithms, and support a +reference-counted mechanism to allow them to be dynamically loaded in and +out of the running application. + +The cryptographic functionality that can be provided by an B +implementation includes the following abstractions; + + RSA_METHOD - for providing alternative RSA implementations + DSA_METHOD, DH_METHOD, RAND_METHOD - alternative DSA, DH, and RAND + EVP_CIPHER - potentially multiple cipher algorithms (indexed by 'nid') + EVP_DIGEST - potentially multiple hash algorithms (indexed by 'nid') + key-loading - loading public and/or private EVP_PKEY keys + +=head2 Reference counting and handles + +Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be +treated as handles - ie. not only as pointers, but also as references to +the underlying ENGINE object. Ie. you should obtain a new reference when +making copies of an ENGINE pointer if the copies will be used (and +released) independantly. + +ENGINE objects have two levels of reference-counting to match the way in +which the objects are used. At the most basic level, each ENGINE pointer is +inherently a B reference - you need a structural reference +simply to refer to the pointer value at all, as this kind of reference is +your guarantee that the structure can not be deallocated until you release +your reference. + +However, a structural reference provides no guarantee that the ENGINE has +been initiliased to be usable to perform any of its cryptographic +implementations - and indeed it's quite possible that most ENGINEs will not +initialised at all on standard setups, as ENGINEs are typically used to +support specialised hardware. To use an ENGINE's functionality, you need a +B reference. This kind of reference can be considered a +specialised form of structural reference, because each functional reference +implicitly contains a structural reference as well - however to avoid +difficult-to-find programming bugs, it is recommended to treat the two +kinds of reference independantly. If you have a functional reference to an +ENGINE, you have a guarantee that the ENGINE has been initialised ready to +perform cryptographic operations and will not be uninitialised or cleaned +up until after you have released your reference. + +We will discuss the two kinds of reference separately, including how to +tell which one you are dealing with at any given point in time (after all +they are both simply (ENGINE *) pointers, the difference is in the way they +are used). + +=head3 Structural references + +This basic type of reference is typically used for creating new ENGINEs +dynamically, iterating across OpenSSL's internal linked-list of loaded +ENGINEs, reading information about an ENGINE, etc. Essentially a structural +reference is sufficient if you only need to query or manipulate the data of +an ENGINE implementation rather than use its functionality. + +The ENGINE_new() function returns a structural reference to a new (empty) +ENGINE object. Other than that, structural references come from return +values to various ENGINE API functions such as; ENGINE_by_id(), +ENGINE_get_first(), ENGINE_get_last(), ENGINE_get_next(), +ENGINE_get_prev(). All structural references should be released by a +corresponding to call to the ENGINE_free() function - the ENGINE object +itself will only actually be cleaned up and deallocated when the last +structural reference is released. + +It should also be noted that many ENGINE API function calls that accept a +structural reference will internally obtain another reference - typically +this happens whenever the supplied ENGINE will be needed by OpenSSL after +the function has returned. Eg. the function to add a new ENGINE to +OpenSSL's internal list is ENGINE_add() - if this function returns success, +then OpenSSL will have stored a new structural reference internally so the +caller is still responsible for freeing their own reference with +ENGINE_free() when they are finished with it. In a similar way, some +functions will automatically release the structural reference passed to it +if part of the function's job is to do so. Eg. the ENGINE_get_next() and +ENGINE_get_prev() functions are used for iterating across the internal +ENGINE list - they will return a new structural reference to the next (or +previous) ENGINE in the list or NULL if at the end (or beginning) of the +list, but in either case the structural reference passed to the function is +released on behalf of the caller. + +To clarify a particular function's handling of references, one should +always consult that function's documentation "man" page, or failing that +the openssl/engine.h header file includes some hints. + +=head3 Functional references + +As mentioned, functional references exist when the cryptographic +functionality of an ENGINE is required to be available. A functional +reference can be obtained in one of two ways; from an existing structural +reference to the required ENGINE, or by asking OpenSSL for the default +operational ENGINE for a given cryptographic purpose. + +To obtain a functional reference from an existing structural reference, +call the ENGINE_init() function. This returns zero if the ENGINE was not +already operational and couldn't be successfully initialised (eg. lack of +system drivers, no special hardware attached, etc), otherwise it will +return non-zero to indicate that the ENGINE is now operational and will +have allocated a new B reference to the ENGINE. In this case, +the supplied ENGINE pointer is, from the point of the view of the caller, +both a structural reference and a functional reference - so if the caller +intends to use it as a functional reference it should free the structural +reference with ENGINE_free() first. If the caller wishes to use it only as +a structural reference (eg. if the ENGINE_init() call was simply to test if +the ENGINE seems available/online), then it should free the functional +reference; all functional references are released by the ENGINE_finish() +function. + +The second way to get a functional reference is by asking OpenSSL for a +default implementation for a given task, eg. by ENGINE_get_default_RSA(), +ENGINE_get_default_cipher_engine(), etc. These are discussed in the next +section, though they are not usually required by application programmers as +they are used automatically when creating and using the relevant +algorithm-specific types in OpenSSL, such as RSA, DSA, EVP_CIPHER_CTX, etc. + +=head2 Default implementations + +For each supported abstraction, the ENGINE code maintains an internal table +of state to control which implementations are available for a given +abstraction and which should be used by default. These implementations are +registered in the tables separated-out by an 'nid' index, because +abstractions like EVP_CIPHER and EVP_DIGEST support many distinct +algorithms and modes - ENGINEs will support different numbers and +combinations of these. In the case of other abstractions like RSA, DSA, +etc, there is only one "algorithm" so all implementations implicitly +register using the same 'nid' index. ENGINEs can be B into +these tables to make themselves available for use automatically by the +various abstractions, eg. RSA. For illustrative purposes, we continue with +the RSA example, though all comments apply similarly to the other +abstractions (they each get their own table and linkage to the +corresponding section of openssl code). + +When a new RSA key is being created, ie. in RSA_new_method(), a +"get_default" call will be made to the ENGINE subsystem to process the RSA +state table and return a functional reference to an initialised ENGINE +whose RSA_METHOD should be used. If no ENGINE should (or can) be used, it +will return NULL and the RSA key will operate with a NULL ENGINE handle by +using the conventional RSA implementation in OpenSSL (and will from then on +behave the way it used to before the ENGINE API existed - for details see +L). + +Each state table has a flag to note whether it has processed this +"get_default" query since the table was last modified, because to process +this question it must iterate across all the registered ENGINEs in the +table trying to initialise each of them in turn, in case one of them is +operational. If it returns a functional reference to an ENGINE, it will +also cache another reference to speed up processing future queries (without +needing to iterate across the table). Likewise, it will cache a NULL +response if no ENGINE was available so that future queries won't repeat the +same iteration unless the state table changes. This behaviour can also be +changed; if the ENGINE_TABLE_FLAG_NOINIT flag is set (using +ENGINE_set_table_flags()), no attempted initialisations will take place, +instead the only way for the state table to return a non-NULL ENGINE to the +"get_default" query will be if one is expressly set in the table. Eg. +ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except +that it also sets the state table's cached response for the "get_default" +query. + +In the case of abstractions like EVP_CIPHER, where implementations are +indexed by 'nid', these flags and cached-responses are distinct for each +'nid' value. + +It is worth illustrating the difference between "registration" of ENGINEs +into these per-algorithm state tables and using the alternative +"set_default" functions. The latter handles both "registration" and also +setting the cached "default" ENGINE in each relevant state table - so +registered ENGINEs will only have a chance to be initialised for use as a +default if a default ENGINE wasn't already set for the same state table. +Eg. if ENGINE X supports cipher nids {A,B} and RSA, ENGINE Y supports +ciphers {A} and DSA, and the following code is executed; + + ENGINE_register_complete(X); + ENGINE_set_default(Y, ENGINE_METHOD_ALL); + e1 = ENGINE_get_default_RSA(); + e2 = ENGINE_get_cipher_engine(A); + e3 = ENGINE_get_cipher_engine(B); + e4 = ENGINE_get_default_DSA(); + e5 = ENGINE_get_cipher_engine(C); + +The results would be as follows; + + assert(e1 == X); + assert(e2 == Y); + assert(e3 == X); + assert(e4 == Y); + assert(e5 == NULL); + +=head2 Application requirements + +This section will explain the basic things an application programmer should +support to make the most useful elements of the ENGINE functionality +available to the user. The first thing to consider is whether the +programmer wishes to make alternative ENGINE modules available to the +application and user. OpenSSL maintains an internal linked list of +"visible" ENGINEs from which it has to operate - at start-up, this list is +empty and in fact if an application does not call any ENGINE API calls and +it uses static linking against openssl, then the resulting application +binary will not contain any alternative ENGINE code at all. So the first +consideration is whether any/all available ENGINE implementations should be +made visible to OpenSSL - this is controlled by calling the various "load" +functions, eg. + + /* Make the "dynamic" ENGINE available */ + void ENGINE_load_dynamic(void); + /* Make the CryptoSwift hardware acceleration support available */ + void ENGINE_load_cswift(void); + /* Make support for nCipher's "CHIL" hardware available */ + void ENGINE_load_chil(void); + ... + /* Make ALL ENGINE implementations bundled with OpenSSL available */ + void ENGINE_load_builtin_engines(void); + +Having called any of these functions, ENGINE objects would have been +dynamically allocated and populated with these implementations and linked +into OpenSSL's internal linked list. At this point it is important to +mention an important API function; + + void ENGINE_cleanup(void); + +If no ENGINE API functions are called at all in an application, then there +are no inherent memory leaks to worry about from the ENGINE functionality, +however if any ENGINEs are "load"ed, even if they are never registered or +used, it is necessary to use the ENGINE_cleanup() function to +correspondingly cleanup before program exit, if the caller wishes to avoid +memory leaks. This mechanism uses an internal callback registration table +so that any ENGINE API functionality that knows it requires cleanup can +register its cleanup details to be called during ENGINE_cleanup(). This +approach allows ENGINE_cleanup() to clean up after any ENGINE functionality +at all that your program uses, yet doesn't automatically create linker +dependencies to all possible ENGINE functionality - only the cleanup +callbacks required by the functionality you do use will be required by the +linker. + +The fact that ENGINEs are made visible to OpenSSL (and thus are linked into +the program and loaded into memory at run-time) does not mean they are +"registered" or called into use by OpenSSL automatically - that behaviour +is something for the application to have control over. Some applications +will want to allow the user to specify exactly which ENGINE they want used +if any is to be used at all. Others may prefer to load all support and have +OpenSSL automatically use at run-time any ENGINE that is able to +successfully initialise - ie. to assume that this corresponds to +acceleration hardware attached to the machine or some such thing. There are +probably numerous other ways in which applications may prefer to handle +things, so we will simply illustrate the consequences as they apply to a +couple of simple cases and leave developers to consider these and the +source code to openssl's builtin utilities as guides. + +=head3 Using a specific ENGINE implementation + +Here we'll assume an application has been configured by its user or admin +to want to use the "ACME" ENGINE if it is available in the version of +OpenSSL the application was compiled with. If it is available, it should be +used by default for all RSA, DSA, and symmetric cipher operation, otherwise +OpenSSL should use its builtin software as per usual. The following code +illustrates how to approach this; + + ENGINE *e; + const char *engine_id = "ACME"; + ENGINE_load_builtin_engines(); + e = ENGINE_by_id(engine_id); + if(!e) + /* the engine isn't available */ + return; + if(!ENGINE_init(e)) { + /* the engine couldn't initialise, release 'e' */ + ENGINE_free(e); + return; + } + if(!ENGINE_set_default_RSA(e)) + /* This should only happen when 'e' can't initialise, but the previous + * statement suggests it did. */ + abort(); + ENGINE_set_default_DSA(e); + ENGINE_set_default_ciphers(e); + /* Release the functional reference from ENGINE_init() */ + ENGINE_finish(e); + /* Release the structural reference from ENGINE_by_id() */ + ENGINE_free(e); + +=head3 Automatically using builtin ENGINE implementations + +Here we'll assume we want to load and register all ENGINE implementations +bundled with OpenSSL, such that for any cryptographic algorithm required by +OpenSSL - if there is an ENGINE that implements it and can be initialise, +it should be used. The following code illustrates how this can work; + + /* Load all bundled ENGINEs into memory and make them visible */ + ENGINE_load_builtin_engines(); + /* Register all of them for every algorithm they collectively implement */ + ENGINE_register_all_complete(); + +That's all that's required. Eg. the next time OpenSSL tries to set up an +RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to +ENGINE_init() and if any of those succeed, that ENGINE will be set as the +default for use with RSA from then on. + +=head2 Advanced configuration support + +There is a mechanism supported by the ENGINE framework that allows each +ENGINE implementation to define an arbitrary set of configuration +"commands" and expose them to OpenSSL and any applications based on +OpenSSL. This mechanism is entirely based on the use of name-value pairs +and and assumes ASCII input (no unicode or UTF for now!), so it is ideal if +applications want to provide a transparent way for users to provide +arbitrary configuration "directives" directly to such ENGINEs. It is also +possible for the application to dynamically interrogate the loaded ENGINE +implementations for the names, descriptions, and input flags of their +available "control commands", providing a more flexible configuration +scheme. However, if the user is expected to know which ENGINE device he/she +is using (in the case of specialised hardware, this goes without saying) +then applications may not need to concern themselves with discovering the +supported control commands and simply prefer to allow settings to passed +into ENGINEs exactly as they are provided by the user. + +Before illustrating how control commands work, it is worth mentioning what +they are typically used for. Broadly speaking there are two uses for +control commands; the first is to provide the necessary details to the +implementation (which may know nothing at all specific to the host system) +so that it can be initialised for use. This could include the path to any +driver or config files it needs to load, required network addresses, +smart-card identifiers, passwords to initialise password-protected devices, +logging information, etc etc. This class of commands typically needs to be +passed to an ENGINE B attempting to initialise it, ie. before +calling ENGINE_init(). The other class of commands consist of settings or +operations that tweak certain behaviour or cause certain operations to take +place, and these commands may work either before or after ENGINE_init(), or +in same cases both. ENGINE implementations should provide indications of +this in the descriptions attached to builtin control commands and/or in +external product documentation. + +=head3 Issuing control commands to an ENGINE + +Let's illustrate by example; a function for which the caller supplies the +name of the ENGINE it wishes to use, a table of string-pairs for use before +initialisation, and another table for use after initialisation. Note that +the string-pairs used for control commands consist of a command "name" +followed by the command "parameter" - the parameter could be NULL in some +cases but the name can not. This function should initialise the ENGINE +(issuing the "pre" commands beforehand and the "post" commands afterwards) +and set it as the default for everything except RAND and then return a +boolean success or failure. + + int generic_load_engine_fn(const char *engine_id, + const char **pre_cmds, int pre_num, + const char **post_cmds, int post_num) + { + ENGINE *e = ENGINE_by_id(engine_id); + if(!e) return 0; + while(pre_num--) { + if(!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) { + fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id, + pre_cmds[0], pre_cmds[1] ? pre_cmds[1] : "(NULL)"); + ENGINE_free(e); + return 0; + } + pre_cmds += 2; + } + if(!ENGINE_init(e)) { + fprintf(stderr, "Failed initialisation\n"); + ENGINE_free(e); + return 0; + } + /* ENGINE_init() returned a functional reference, so free the structural + * reference from ENGINE_by_id(). */ + ENGINE_free(e); + while(post_num--) { + if(!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) { + fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id, + post_cmds[0], post_cmds[1] ? post_cmds[1] : "(NULL)"); + ENGINE_finish(e); + return 0; + } + post_cmds += 2; + } + ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND); + /* Success */ + return 1; + } + +Note that ENGINE_ctrl_cmd_string() accepts a boolean argument that can +relax the semantics of the function - if set non-zero it will only return +failure if the ENGINE supported the given command name but failed while +executing it, if the ENGINE doesn't support the command name it will simply +return success without doing anything. In this case we assume the user is +only supplying commands specific to the given ENGINE so we set this to +FALSE. + +=head3 Discovering supported control commands + +It is possible to discover at run-time the names, numerical-ids, descriptions +and input parameters of the control commands supported from a structural +reference to any ENGINE. It is first important to note that some control +commands are defined by OpenSSL itself and it will intercept and handle these +control commands on behalf of the ENGINE, ie. the ENGINE's ctrl() handler is not +used for the control command. openssl/engine.h defines a symbol, +ENGINE_CMD_BASE, that all control commands implemented by ENGINEs from. Any +command value lower than this symbol is considered a "generic" command is +handled directly by the OpenSSL core routines. + +It is using these "core" control commands that one can discover the the control +commands implemented by a given ENGINE, specifically the commands; + + #define ENGINE_HAS_CTRL_FUNCTION 10 + #define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 + #define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 + #define ENGINE_CTRL_GET_CMD_FROM_NAME 13 + #define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 + #define ENGINE_CTRL_GET_NAME_FROM_CMD 15 + #define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 + #define ENGINE_CTRL_GET_DESC_FROM_CMD 17 + #define ENGINE_CTRL_GET_CMD_FLAGS 18 + +Whilst these commands are automatically processed by the OpenSSL framework code, +they use various properties exposed by each ENGINE by which to process these +queries. An ENGINE has 3 properties it exposes that can affect this behaviour; +it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in +the ENGINE's flags, and it can expose an array of control command descriptions. +If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will +simply pass all these "core" control commands directly to the ENGINE's ctrl() +handler (and thus, it must have supplied one), so it is up to the ENGINE to +reply to these "discovery" commands itself. If that flag is not set, then the +OpenSSL framework code will work with the following rules; + + if no ctrl() handler supplied; + ENGINE_HAS_CTRL_FUNCTION returns FALSE (zero), + all other commands fail. + if a ctrl() handler was supplied but no array of control commands; + ENGINE_HAS_CTRL_FUNCTION returns TRUE, + all other commands fail. + if a ctrl() handler and array of control commands was supplied; + ENGINE_HAS_CTRL_FUNCTION returns TRUE, + all other commands proceed processing ... + +If the ENGINE's array of control commands is empty then all other commands will +fail, otherwise; ENGINE_CTRL_GET_FIRST_CMD_TYPE returns the identifier of +the first command supported by the ENGINE, ENGINE_GET_NEXT_CMD_TYPE takes the +identifier of a command supported by the ENGINE and returns the next command +identifier or fails if there are no more, ENGINE_CMD_FROM_NAME takes a string +name for a command and returns the corresponding identifier or fails if no such +command name exists, and the remaining commands take a command identifier and +return properties of the corresponding commands. All except +ENGINE_CTRL_GET_FLAGS return the string length of a command name or description, +or populate a supplied character buffer with a copy of the command name or +description. ENGINE_CTRL_GET_FLAGS returns a bitwise-OR'd mask of the following +possible values; + + #define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 + #define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 + #define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 + #define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +If the ENGINE_CMD_FLAG_INTERNAL flag is set, then any other flags are purely +informational to the caller - this flag will prevent the command being usable +for any higher-level ENGINE functions such as ENGINE_ctrl_cmd_string(). +"INTERNAL" commands are not intended to be exposed to text-based configuration +by applications, administrations, users, etc. These can support arbitrary +operations via ENGINE_ctrl(), including passing to and/or from the control +commands data of any arbitrary type. These commands are supported in the +discovery mechanisms simply to allow applications determinie if an ENGINE +supports certain specific commands it might want to use (eg. application "foo" +might query various ENGINEs to see if they implement "FOO_GET_VENDOR_LOGO_GIF" - +and ENGINE could therefore decide whether or not to support this "foo"-specific +extension). + +=head2 Future developments + +The ENGINE API and internal architecture is currently being reviewed. Slated for +possible release in 0.9.8 is support for transparent loading of "dynamic" +ENGINEs (built as self-contained shared-libraries). This would allow ENGINE +implementations to be provided independantly of OpenSSL libraries and/or +OpenSSL-based applications, and would also remove any requirement for +applications to explicitly use the "dynamic" ENGINE to bind to shared-library +implementations. + +=head1 SEE ALSO + +L, L, L, L, +L + +=cut diff --git a/src/lib/libcrypto/doc/evp.pod b/src/lib/libcrypto/doc/evp.pod index edf47dbde6..b3ca14314f 100644 --- a/src/lib/libcrypto/doc/evp.pod +++ b/src/lib/libcrypto/doc/evp.pod @@ -24,6 +24,13 @@ functions. The BI<...> functions provide message digests. Algorithms are loaded with OpenSSL_add_all_algorithms(3). +All the symmetric algorithms (ciphers) and digests can be replaced by ENGINE +modules providing alternative implementations. If ENGINE implementations of +ciphers or digests are registered as defaults, then the various EVP functions +will automatically use those implementations automatically in preference to +built in software implementations. For more information, consult the engine(3) +man page. + =head1 SEE ALSO L, @@ -32,6 +39,7 @@ L, L, L, L, -L +L, +L =cut diff --git a/src/lib/libcrypto/doc/rsa.pod b/src/lib/libcrypto/doc/rsa.pod index 2b93a12b65..45ac53ffc1 100644 --- a/src/lib/libcrypto/doc/rsa.pod +++ b/src/lib/libcrypto/doc/rsa.pod @@ -16,13 +16,17 @@ rsa - RSA public key cryptosystem unsigned char *to, RSA *rsa, int padding); int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding); + int RSA_private_encrypt(int flen, unsigned char *from, + unsigned char *to, RSA *rsa,int padding); + int RSA_public_decrypt(int flen, unsigned char *from, + unsigned char *to, RSA *rsa,int padding); int RSA_sign(int type, unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa); int RSA_verify(int type, unsigned char *m, unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, RSA *rsa); - int RSA_size(RSA *rsa); + int RSA_size(const RSA *rsa); RSA *RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg); @@ -32,13 +36,13 @@ rsa - RSA public key cryptosystem int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); void RSA_blinding_off(RSA *rsa); - void RSA_set_default_openssl_method(RSA_METHOD *meth); - RSA_METHOD *RSA_get_default_openssl_method(void); - int RSA_set_method(RSA *rsa, ENGINE *engine); - RSA_METHOD *RSA_get_method(RSA *rsa); + void RSA_set_default_method(const RSA_METHOD *meth); + const RSA_METHOD *RSA_get_default_method(void); + int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + const RSA_METHOD *RSA_get_method(const RSA *rsa); RSA_METHOD *RSA_PKCS1_SSLeay(void); RSA_METHOD *RSA_null_method(void); - int RSA_flags(RSA *rsa); + int RSA_flags(const RSA *rsa); RSA *RSA_new_method(ENGINE *engine); int RSA_print(BIO *bp, RSA *x, int offset); @@ -49,11 +53,6 @@ rsa - RSA public key cryptosystem int RSA_set_ex_data(RSA *r,int idx,char *arg); char *RSA_get_ex_data(RSA *r, int idx); - int RSA_private_encrypt(int flen, unsigned char *from, - unsigned char *to, RSA *rsa,int padding); - int RSA_public_decrypt(int flen, unsigned char *from, - unsigned char *to, RSA *rsa,int padding); - int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa); @@ -90,6 +89,14 @@ B

, B, B, B and B may be B in private keys, but the RSA operations are much faster when these values are available. +Note that RSA keys may use non-standard B implementations, +either directly or by the use of B modules. In some cases (eg. an +ENGINE providing support for hardware-embedded keys), these BIGNUM values +will not be used by the implementation or may be used for alternative data +storage. For this reason, applications should generally avoid using RSA +structure elements directly and instead use API functions to query or +modify keys. + =head1 CONFORMING TO SSL, PKCS #1 v2.0 @@ -101,7 +108,7 @@ RSA was covered by a US patent which expired in September 2000. =head1 SEE ALSO L, L, L, L, -L, L, +L, L, L, L, L, L, L, diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h index 7b088b4848..4d81a3bf4c 100644 --- a/src/lib/libcrypto/evp/evp_locl.h +++ b/src/lib/libcrypto/evp/evp_locl.h @@ -124,17 +124,17 @@ const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; } BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \ iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl) -#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, block_size, key_len, \ +#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \ iv_len, cbits, flags, init_key, cleanup, \ set_asn1, get_asn1, ctrl) \ -BLOCK_CIPHER_def1(cname, cfb##cbits, cfb, CFB, kstruct, nid, block_size, \ +BLOCK_CIPHER_def1(cname, cfb##cbits, cfb, CFB, kstruct, nid, 1, \ key_len, iv_len, flags, init_key, cleanup, set_asn1, \ get_asn1, ctrl) -#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, block_size, key_len, \ +#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \ iv_len, cbits, flags, init_key, cleanup, \ set_asn1, get_asn1, ctrl) \ -BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, block_size, \ +BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \ key_len, iv_len, flags, init_key, cleanup, set_asn1, \ get_asn1, ctrl) @@ -149,9 +149,9 @@ BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \ init_key, cleanup, set_asn1, get_asn1, ctrl) \ BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \ init_key, cleanup, set_asn1, get_asn1, ctrl) \ -BLOCK_CIPHER_def_cfb(cname, kstruct, nid, block_size, key_len, iv_len, cbits, \ +BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \ -BLOCK_CIPHER_def_ofb(cname, kstruct, nid, block_size, key_len, iv_len, cbits, \ +BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \ BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \ init_key, cleanup, set_asn1, get_asn1, ctrl) diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c index 02c3719f04..ce779dc1b5 100644 --- a/src/lib/libcrypto/objects/obj_dat.c +++ b/src/lib/libcrypto/objects/obj_dat.c @@ -425,7 +425,7 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) a2d_ASN1_OBJECT(p,i,s,-1); p=buf; - op=d2i_ASN1_OBJECT(NULL,&p,i); + op=d2i_ASN1_OBJECT(NULL,&p,j); OPENSSL_free(buf); return op; } diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c index 18b751a91a..a8db6ffbf5 100644 --- a/src/lib/libcrypto/pem/pem_lib.c +++ b/src/lib/libcrypto/pem/pem_lib.c @@ -366,8 +366,11 @@ err: memset(iv,0,sizeof(iv)); memset((char *)&ctx,0,sizeof(ctx)); memset(buf,0,PEM_BUFSIZE); - memset(data,0,(unsigned int)dsize); - OPENSSL_free(data); + if (data != NULL) + { + memset(data,0,(unsigned int)dsize); + OPENSSL_free(data); + } return(ret); } diff --git a/src/lib/libcrypto/pkcs12/p12_asn.c b/src/lib/libcrypto/pkcs12/p12_asn.c index c327bdba03..a3739fee1a 100644 --- a/src/lib/libcrypto/pkcs12/p12_asn.c +++ b/src/lib/libcrypto/pkcs12/p12_asn.c @@ -83,8 +83,8 @@ ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0) ASN1_ADB(PKCS12_BAGS) = { ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)), - ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), - ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), + ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), } ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL); ASN1_SEQUENCE(PKCS12_BAGS) = { @@ -98,7 +98,7 @@ ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ ASN1_ADB(PKCS12_SAFEBAG) = { ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)), - ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, X509_SIG, 0)), + ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)), ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)), ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c index c00ed6833a..985b07245c 100644 --- a/src/lib/libcrypto/pkcs7/pk7_lib.c +++ b/src/lib/libcrypto/pkcs7/pk7_lib.c @@ -74,6 +74,13 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) if (nid == NID_pkcs7_signed) { ret=p7->detached=(int)larg; + if (ret && PKCS7_type_is_data(p7->d.sign->contents)) + { + ASN1_OCTET_STRING *os; + os=p7->d.sign->contents->d.data; + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } } else { diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h index c75aa0c717..7095440d36 100644 --- a/src/lib/libcrypto/x509/x509.h +++ b/src/lib/libcrypto/x509/x509.h @@ -331,6 +331,7 @@ DECLARE_STACK_OF(X509_TRUST) #define X509_FLAG_NO_EXTENSIONS (1L << 8) #define X509_FLAG_NO_SIGDUMP (1L << 9) #define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) /* Flags specific to X509_NAME_print_ex() */ @@ -1015,6 +1016,7 @@ int X509_print(BIO *bp,X509 *x); int X509_ocspid_print(BIO *bp,X509 *x); int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); int X509_CRL_print(BIO *bp,X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); int X509_REQ_print(BIO *bp,X509_REQ *req); #endif diff --git a/src/lib/libssl/doc/openssl.txt b/src/lib/libssl/doc/openssl.txt index 5da519e7e4..432a17b66c 100644 --- a/src/lib/libssl/doc/openssl.txt +++ b/src/lib/libssl/doc/openssl.txt @@ -344,7 +344,7 @@ the extension. Examples: -subjectAltName=email:copy,email:my@other.address,URL:http://my.url.here/ +subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/ subjectAltName=email:my@other.address,RID:1.2.3.4 Issuer Alternative Name. diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c index 2699b5863b..2b58482484 100644 --- a/src/lib/libssl/s3_clnt.c +++ b/src/lib/libssl/s3_clnt.c @@ -546,7 +546,11 @@ static int ssl3_client_hello(SSL *s) *(p++)=i; if (i != 0) { - die(i <= sizeof s->session->session_id); + if (i > sizeof s->session->session_id) + { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } memcpy(p,s->session->session_id,i); p+=i; } @@ -1598,7 +1602,11 @@ static int ssl3_send_client_key_exchange(SSL *s) SSL_MAX_MASTER_KEY_LENGTH); EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); outl += padl; - die(outl <= sizeof epms); + if (outl > sizeof epms) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } EVP_CIPHER_CTX_cleanup(&ciph_ctx); /* KerberosWrapper.EncryptedPreMasterSecret */ diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c index 782b57f57a..20d716fb1b 100644 --- a/src/lib/libssl/s3_srvr.c +++ b/src/lib/libssl/s3_srvr.c @@ -965,7 +965,11 @@ static int ssl3_send_server_hello(SSL *s) s->session->session_id_length=0; sl=s->session->session_id_length; - die(sl <= sizeof s->session->session_id); + if (sl > sizeof s->session->session_id) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } *(p++)=sl; memcpy(p,s->session->session_id,sl); p+=sl; @@ -1588,7 +1592,7 @@ static int ssl3_get_client_key_exchange(SSL *s) /* Note that the length is checked again below, ** after decryption */ - if(enc.pms_length > sizeof pms) + if(enc_pms.length > sizeof pms) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index d9949e8eb2..e9d1e896d7 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -1462,6 +1462,7 @@ void ERR_load_SSL_strings(void); /* Function codes. */ #define SSL_F_CLIENT_CERTIFICATE 100 +#define SSL_F_CLIENT_FINISHED 238 #define SSL_F_CLIENT_HELLO 101 #define SSL_F_CLIENT_MASTER_KEY 102 #define SSL_F_D2I_SSL_SESSION 103 @@ -1475,7 +1476,9 @@ void ERR_load_SSL_strings(void); #define SSL_F_I2D_SSL_SESSION 111 #define SSL_F_READ_N 112 #define SSL_F_REQUEST_CERTIFICATE 113 +#define SSL_F_SERVER_FINISH 239 #define SSL_F_SERVER_HELLO 114 +#define SSL_F_SERVER_VERIFY 240 #define SSL_F_SSL23_ACCEPT 115 #define SSL_F_SSL23_CLIENT_HELLO 116 #define SSL_F_SSL23_CONNECT 117 @@ -1487,6 +1490,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL2_ACCEPT 122 #define SSL_F_SSL2_CONNECT 123 #define SSL_F_SSL2_ENC_INIT 124 +#define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 #define SSL_F_SSL2_PEEK 234 #define SSL_F_SSL2_READ 125 #define SSL_F_SSL2_READ_INTERNAL 236 @@ -1523,6 +1527,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 #define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 #define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +#define SSL_F_SSL3_SEND_SERVER_HELLO 242 #define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 #define SSL_F_SSL3_SETUP_BUFFERS 156 #define SSL_F_SSL3_SETUP_KEY_BLOCK 157 @@ -1747,6 +1752,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 1114 #define SSL_R_SSL3_SESSION_ID_TOO_LONG 1113 #define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 diff --git a/src/lib/libssl/ssl_asn1.c b/src/lib/libssl/ssl_asn1.c index 1638c6b525..3723fc2e37 100644 --- a/src/lib/libssl/ssl_asn1.c +++ b/src/lib/libssl/ssl_asn1.c @@ -294,10 +294,11 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, unsigned char **pp, i=SSL2_MAX_SSL_SESSION_ID_LENGTH; if (os.length > i) - os.length=i; + os.length = i; + if (os.length > sizeof ret->session_id) /* can't happen */ + os.length = sizeof ret->session_id; ret->session_id_length=os.length; - die(os.length <= sizeof ret->session_id); memcpy(ret->session_id,os.data,os.length); M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING); diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c index 0cad32c855..7067a745f3 100644 --- a/src/lib/libssl/ssl_err.c +++ b/src/lib/libssl/ssl_err.c @@ -67,6 +67,7 @@ static ERR_STRING_DATA SSL_str_functs[]= { {ERR_PACK(0,SSL_F_CLIENT_CERTIFICATE,0), "CLIENT_CERTIFICATE"}, +{ERR_PACK(0,SSL_F_CLIENT_FINISHED,0), "CLIENT_FINISHED"}, {ERR_PACK(0,SSL_F_CLIENT_HELLO,0), "CLIENT_HELLO"}, {ERR_PACK(0,SSL_F_CLIENT_MASTER_KEY,0), "CLIENT_MASTER_KEY"}, {ERR_PACK(0,SSL_F_D2I_SSL_SESSION,0), "d2i_SSL_SESSION"}, @@ -80,7 +81,9 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_I2D_SSL_SESSION,0), "i2d_SSL_SESSION"}, {ERR_PACK(0,SSL_F_READ_N,0), "READ_N"}, {ERR_PACK(0,SSL_F_REQUEST_CERTIFICATE,0), "REQUEST_CERTIFICATE"}, +{ERR_PACK(0,SSL_F_SERVER_FINISH,0), "SERVER_FINISH"}, {ERR_PACK(0,SSL_F_SERVER_HELLO,0), "SERVER_HELLO"}, +{ERR_PACK(0,SSL_F_SERVER_VERIFY,0), "SERVER_VERIFY"}, {ERR_PACK(0,SSL_F_SSL23_ACCEPT,0), "SSL23_ACCEPT"}, {ERR_PACK(0,SSL_F_SSL23_CLIENT_HELLO,0), "SSL23_CLIENT_HELLO"}, {ERR_PACK(0,SSL_F_SSL23_CONNECT,0), "SSL23_CONNECT"}, @@ -92,6 +95,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL2_ACCEPT,0), "SSL2_ACCEPT"}, {ERR_PACK(0,SSL_F_SSL2_CONNECT,0), "SSL2_CONNECT"}, {ERR_PACK(0,SSL_F_SSL2_ENC_INIT,0), "SSL2_ENC_INIT"}, +{ERR_PACK(0,SSL_F_SSL2_GENERATE_KEY_MATERIAL,0), "SSL2_GENERATE_KEY_MATERIAL"}, {ERR_PACK(0,SSL_F_SSL2_PEEK,0), "SSL2_PEEK"}, {ERR_PACK(0,SSL_F_SSL2_READ,0), "SSL2_READ"}, {ERR_PACK(0,SSL_F_SSL2_READ_INTERNAL,0), "SSL2_READ_INTERNAL"}, @@ -128,6 +132,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,0), "SSL3_SEND_CLIENT_KEY_EXCHANGE"}, {ERR_PACK(0,SSL_F_SSL3_SEND_CLIENT_VERIFY,0), "SSL3_SEND_CLIENT_VERIFY"}, {ERR_PACK(0,SSL_F_SSL3_SEND_SERVER_CERTIFICATE,0), "SSL3_SEND_SERVER_CERTIFICATE"}, +{ERR_PACK(0,SSL_F_SSL3_SEND_SERVER_HELLO,0), "SSL3_SEND_SERVER_HELLO"}, {ERR_PACK(0,SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,0), "SSL3_SEND_SERVER_KEY_EXCHANGE"}, {ERR_PACK(0,SSL_F_SSL3_SETUP_BUFFERS,0), "SSL3_SETUP_BUFFERS"}, {ERR_PACK(0,SSL_F_SSL3_SETUP_KEY_BLOCK,0), "SSL3_SETUP_KEY_BLOCK"}, @@ -355,6 +360,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_SHORT_READ ,"short read"}, {SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE,"signature for non signing certificate"}, {SSL_R_SSL23_DOING_SESSION_ID_REUSE ,"ssl23 doing session id reuse"}, +{SSL_R_SSL2_CONNECTION_ID_TOO_LONG ,"ssl2 connection id too long"}, {SSL_R_SSL3_SESSION_ID_TOO_LONG ,"ssl3 session id too long"}, {SSL_R_SSL3_SESSION_ID_TOO_SHORT ,"ssl3 session id too short"}, {SSL_R_SSLV3_ALERT_BAD_CERTIFICATE ,"sslv3 alert bad certificate"}, diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index ab172aeaec..4bc4ce5b3a 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -1405,13 +1405,24 @@ void SSL_CTX_free(SSL_CTX *a) abort(); /* ok */ } #endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); + /* + * Free internal session cache. However: the remove_cb() may reference + * the ex_data of SSL_CTX, thus the ex_data store can only be removed + * after the sessions were flushed. + * As the ex_data handling routines might also touch the session cache, + * the most secure solution seems to be: empty (flush) the cache, then + * free ex_data, then finally free the cache. + * (See ticket [openssl.org #212].) + */ if (a->sessions != NULL) - { SSL_CTX_flush_sessions(a,0); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); + + if (a->sessions != NULL) lh_free(a->sessions); - } + if (a->cert_store != NULL) X509_STORE_free(a->cert_store); if (a->cipher_list != NULL) diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index fe4ac839cf..dd6c7a7323 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h @@ -510,7 +510,7 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); int ssl_verify_alarm_type(long type); int ssl2_enc_init(SSL *s, int client); -void ssl2_generate_key_material(SSL *s); +int ssl2_generate_key_material(SSL *s); void ssl2_enc(SSL *s,int send_data); void ssl2_mac(SSL *s,unsigned char *mac,int send_data); SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c index 8bfc382bb6..ca1a7427be 100644 --- a/src/lib/libssl/ssl_sess.c +++ b/src/lib/libssl/ssl_sess.c @@ -251,7 +251,12 @@ int ssl_get_new_session(SSL *s, int session) ss->session_id_length=0; } - die(s->sid_ctx_length <= sizeof ss->sid_ctx); + if (s->sid_ctx_length > sizeof ss->sid_ctx) + { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length); ss->sid_ctx_length=s->sid_ctx_length; s->session=ss; -- cgit v1.2.3-55-g6feb