Initial, incomplete support for typesafe macros without using function

casts.
This commit is contained in:
Dr. Stephen Henson 2006-11-16 00:19:39 +00:00
parent 28b987aec9
commit de12116417
15 changed files with 111 additions and 30 deletions

View file

@ -4,6 +4,13 @@
Changes between 0.9.8e and 0.9.9 [xx XXX xxxx] Changes between 0.9.8e and 0.9.9 [xx XXX xxxx]
*) Initial incomplete changes to avoid need for function casts in OpenSSL
when OPENSSL_NO_FCAST is set: some compilers (gcc 4.2 and later) reject
their use. Safestack is reimplemented using inline functions: tests show
that these calls are typically optimized away by compilers so they have
no additional overhead. Update ASN1 to avoid use of legacy functions.
[Steve Henson]
*) Win32/64 targets are linked with Winsock2. *) Win32/64 targets are linked with Winsock2.
[Andy Polyakov] [Andy Polyakov]

View file

@ -518,12 +518,18 @@ typedef struct asn1_type_st
* contain the set or sequence bytes */ * contain the set or sequence bytes */
ASN1_STRING * set; ASN1_STRING * set;
ASN1_STRING * sequence; ASN1_STRING * sequence;
ASN1_VALUE * asn1_value;
} value; } value;
} ASN1_TYPE; } ASN1_TYPE;
DECLARE_STACK_OF(ASN1_TYPE) DECLARE_STACK_OF(ASN1_TYPE)
DECLARE_ASN1_SET_OF(ASN1_TYPE) DECLARE_ASN1_SET_OF(ASN1_TYPE)
typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
typedef struct NETSCAPE_X509_st typedef struct NETSCAPE_X509_st
{ {
ASN1_OCTET_STRING *header; ASN1_OCTET_STRING *header;

View file

@ -442,9 +442,9 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
ASN1_TYPE *ret = NULL; ASN1_TYPE *ret = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL; STACK_OF(CONF_VALUE) *sect = NULL;
unsigned char *der = NULL, *p; unsigned char *der = NULL;
int derlen; int derlen;
int i, is_set; int i;
sk = sk_ASN1_TYPE_new_null(); sk = sk_ASN1_TYPE_new_null();
if (section) if (section)
{ {
@ -465,17 +465,9 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
/* Now we has a STACK of the components, convert to the correct form */ /* Now we has a STACK of the components, convert to the correct form */
if (utype == V_ASN1_SET) if (utype == V_ASN1_SET)
is_set = 1; derlen = i2d_ASN1_SET_ANY(sk, &der);
else else
is_set = 0; derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype,
V_ASN1_UNIVERSAL, is_set);
der = OPENSSL_malloc(derlen);
p = der;
i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype,
V_ASN1_UNIVERSAL, is_set);
if (!(ret = ASN1_TYPE_new())) if (!(ret = ASN1_TYPE_new()))
goto bad; goto bad;

View file

@ -124,8 +124,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
* by analyzing it we can determine the passed structure: this * by analyzing it we can determine the passed structure: this
* assumes the input is surrounded by an ASN1 SEQUENCE. * assumes the input is surrounded by an ASN1 SEQUENCE.
*/ */
inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
/* Since we only need to discern "traditional format" RSA and DSA /* Since we only need to discern "traditional format" RSA and DSA
* keys we can just count the elements. * keys we can just count the elements.
*/ */

View file

@ -106,7 +106,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt,
} }
astype->type = V_ASN1_SEQUENCE; astype->type = V_ASN1_SEQUENCE;
if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM, if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM),
&astype->value.sequence)) { &astype->value.sequence)) {
ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
goto err; goto err;

View file

@ -188,7 +188,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
&pbe2->keyfunc->parameter->value.sequence)) goto merr; &pbe2->keyfunc->parameter->value.sequence)) goto merr;
pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
@ -204,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
/* Encode PBE2PARAM into parameter */ /* Encode PBE2PARAM into parameter */
if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
&ret->parameter->value.sequence)) goto merr; &ret->parameter->value.sequence)) goto merr;
ret->parameter->type = V_ASN1_SEQUENCE; ret->parameter->type = V_ASN1_SEQUENCE;

View file

@ -114,6 +114,8 @@ unsigned long ASN1_tag2bit(int tag)
/* Macro to initialize and invalidate the cache */ /* Macro to initialize and invalidate the cache */
#define asn1_tlc_clear(c) if (c) (c)->valid = 0 #define asn1_tlc_clear(c) if (c) (c)->valid = 0
/* Version to avoid compiler warning about 'c' always non-NULL */
#define asn1_tlc_clear_nc(c) (c)->valid = 0
/* Decode an ASN1 item, this currently behaves just /* Decode an ASN1 item, this currently behaves just
* like a standard 'd2i' function. 'in' points to * like a standard 'd2i' function. 'in' points to
@ -130,7 +132,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
ASN1_VALUE *ptmpval = NULL; ASN1_VALUE *ptmpval = NULL;
if (!pval) if (!pval)
pval = &ptmpval; pval = &ptmpval;
asn1_tlc_clear(&c); asn1_tlc_clear_nc(&c);
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval; return *pval;
return NULL; return NULL;
@ -140,7 +142,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len, const ASN1_TEMPLATE *tt) const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
{ {
ASN1_TLC c; ASN1_TLC c;
asn1_tlc_clear(&c); asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
} }
@ -944,7 +946,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
if (utype != typ->type) if (utype != typ->type)
ASN1_TYPE_set(typ, utype, NULL); ASN1_TYPE_set(typ, utype, NULL);
opval = pval; opval = pval;
pval = (ASN1_VALUE **)&typ->value.ptr; pval = &typ->value.asn1_value;
} }
switch(utype) switch(utype)
{ {

View file

@ -597,7 +597,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
typ = (ASN1_TYPE *)*pval; typ = (ASN1_TYPE *)*pval;
utype = typ->type; utype = typ->type;
*putype = utype; *putype = utype;
pval = (ASN1_VALUE **)&typ->value.ptr; pval = &typ->value.asn1_value;
} }
else utype = *putype; else utype = *putype;

View file

@ -221,7 +221,7 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{ {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval; ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type; utype = typ->type;
pval = (ASN1_VALUE **)&typ->value.ptr; pval = &typ->value.asn1_value;
if (!*pval) if (!*pval)
return; return;
} }

View file

@ -533,7 +533,7 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
{ {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld; ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type; utype = atype->type;
fld = (ASN1_VALUE **)&atype->value.ptr; fld = &atype->value.asn1_value;
str = (ASN1_STRING *)*fld; str = (ASN1_STRING *)*fld;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
pname = NULL; pname = NULL;

View file

@ -135,3 +135,14 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
/* Special, OCTET STRING with indefinite length constructed support */ /* Special, OCTET STRING with indefinite length constructed support */
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)

View file

@ -79,8 +79,6 @@ typedef struct
} CONF_VALUE; } CONF_VALUE;
DECLARE_STACK_OF(CONF_VALUE) DECLARE_STACK_OF(CONF_VALUE)
DECLARE_STACK_OF(CONF_MODULE)
DECLARE_STACK_OF(CONF_IMODULE)
struct conf_st; struct conf_st;
struct conf_method_st; struct conf_method_st;
@ -105,6 +103,9 @@ struct conf_method_st
typedef struct conf_imodule_st CONF_IMODULE; typedef struct conf_imodule_st CONF_IMODULE;
typedef struct conf_module_st CONF_MODULE; typedef struct conf_module_st CONF_MODULE;
DECLARE_STACK_OF(CONF_MODULE)
DECLARE_STACK_OF(CONF_IMODULE)
/* DSO module function typedefs */ /* DSO module function typedefs */
typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
typedef void conf_finish_func(CONF_IMODULE *md); typedef void conf_finish_func(CONF_IMODULE *md);

View file

@ -205,9 +205,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
{ {
ASN1_TYPE *t1, *t2; ASN1_TYPE *t1, *t2;
if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pklen, if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)));
d2i_ASN1_TYPE,
ASN1_TYPE_free)))
goto decerr; goto decerr;
if (sk_ASN1_TYPE_num(ndsa) != 2) if (sk_ASN1_TYPE_num(ndsa) != 2)
goto decerr; goto decerr;

View file

@ -1,5 +1,5 @@
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -57,6 +57,69 @@
#include <openssl/stack.h> #include <openssl/stack.h>
#ifdef OPENSSL_NO_FCAST
#ifndef OPENSSL_INLINE
#define OPENSSL_INLINE static inline
#endif
#define STACK_OF(type) struct stack_st_##type
#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
#define DECLARE_STACK_OF(type) \
STACK_OF(type) \
{ \
STACK stack; \
}; \
OPENSSL_INLINE STACK_OF(type) *sk_##type##_new( \
int (*cmp)(const type * const *, const type *const *)) \
{ return (STACK_OF(type) *)sk_new((int (*)())cmp); } \
OPENSSL_INLINE STACK_OF(type) *sk_##type##_new_null() \
{ return (STACK_OF(type) *)sk_new_null(); } \
OPENSSL_INLINE void sk_##type##_free(STACK_OF(type) *sk) \
{ sk_free((STACK *)sk); } \
OPENSSL_INLINE int sk_##type##_num(const STACK_OF(type) *sk) \
{ return M_sk_num((const STACK *)sk); } \
OPENSSL_INLINE type *sk_##type##_value(const STACK_OF(type) *sk,int n) \
{ return (type *)sk_value((STACK *)sk,n); } \
OPENSSL_INLINE type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v) \
{ return (type *)(sk_set((STACK *)sk,n,(char *)v)); } \
OPENSSL_INLINE void sk_##type##_zero(STACK_OF(type) *sk) \
{ sk_zero((STACK *)sk); } \
OPENSSL_INLINE int sk_##type##_push(STACK_OF(type) *sk,type *v) \
{ return sk_push((STACK *)sk,(char *)v); } \
OPENSSL_INLINE int sk_##type##_unshift(STACK_OF(type) *sk,type *v) \
{ return sk_unshift((STACK *)sk,(char *)v); } \
OPENSSL_INLINE int sk_##type##_find(STACK_OF(type) *sk,type *v) \
{ return sk_find((STACK *)sk,(char *)v); } \
OPENSSL_INLINE type *sk_##type##_delete(STACK_OF(type) *sk,int n) \
{ return (type *)sk_delete((STACK *)sk,n); } \
OPENSSL_INLINE void sk_##type##_delete_ptr(STACK_OF(type) *sk,type *v) \
{ sk_delete_ptr((STACK *)sk,(char *)v); } \
OPENSSL_INLINE int sk_##type##_insert(STACK_OF(type) *sk,type *v,int n) \
{ return sk_insert((STACK *)sk,(char *)v,n); } \
OPENSSL_INLINE int (*sk_##type##_set_cmp_func(STACK_OF(type) *sk, \
int (*cmp)(const type * const *,const type * const *))) \
(const type *const *,const type *const *) \
{ return (int (*)(const type * const *,const type *const *)) \
sk_set_cmp_func((STACK *)sk,(int(*)(const char * const *, const char * const *))cmp); } \
OPENSSL_INLINE STACK_OF(type) *sk_##type##_dup(STACK_OF(type) *sk) \
{ return (STACK_OF(type) *)sk_dup((STACK *)sk); } \
OPENSSL_INLINE void sk_##type##_pop_free(STACK_OF(type) *sk,void (*func)(type *)) \
{ sk_pop_free((STACK *)sk,(void (*)(void *))func); } \
OPENSSL_INLINE type *sk_##type##_shift(STACK_OF(type) *sk) \
{ return (type *)sk_shift((STACK *)sk); } \
OPENSSL_INLINE type *sk_##type##_pop(STACK_OF(type) *sk) \
{ return (type *)sk_pop((STACK *)sk); } \
OPENSSL_INLINE void sk_##type##_sort(STACK_OF(type) *sk) \
{ sk_sort((STACK *)sk); } \
OPENSSL_INLINE int sk_##type##_is_sorted(const STACK_OF(type) *sk) \
{ return sk_is_sorted((const STACK *)sk); }
#else
typedef void (*openssl_fptr)(void); typedef void (*openssl_fptr)(void);
#define openssl_fcast(f) ((openssl_fptr)f) #define openssl_fcast(f) ((openssl_fptr)f)
@ -1918,4 +1981,6 @@ STACK_OF(type) \
SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
/* End of util/mkstack.pl block, you may now edit :-) */ /* End of util/mkstack.pl block, you may now edit :-) */
#endif
#endif /* !defined HEADER_SAFESTACK_H */ #endif /* !defined HEADER_SAFESTACK_H */

View file

@ -287,8 +287,8 @@ UI_METHOD *UI_OpenSSL(void);
/* The UI_STRING type is the data structure that contains all the needed info /* The UI_STRING type is the data structure that contains all the needed info
about a string or a prompt, including test data for a verification prompt. about a string or a prompt, including test data for a verification prompt.
*/ */
DECLARE_STACK_OF(UI_STRING)
typedef struct ui_string_st UI_STRING; typedef struct ui_string_st UI_STRING;
DECLARE_STACK_OF(UI_STRING)
/* The different types of strings that are currently supported. /* The different types of strings that are currently supported.
This is only needed by method authors. */ This is only needed by method authors. */