Initial, incomplete support for typesafe macros without using function
authorDr. Stephen Henson <steve@openssl.org>
Thu, 16 Nov 2006 00:19:39 +0000 (00:19 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 16 Nov 2006 00:19:39 +0000 (00:19 +0000)
casts.

15 files changed:
CHANGES
crypto/asn1/asn1.h
crypto/asn1/asn1_gen.c
crypto/asn1/d2i_pr.c
crypto/asn1/p5_pbe.c
crypto/asn1/p5_pbev2.c
crypto/asn1/tasn_dec.c
crypto/asn1/tasn_enc.c
crypto/asn1/tasn_fre.c
crypto/asn1/tasn_prn.c
crypto/asn1/tasn_typ.c
crypto/conf/conf.h
crypto/dsa/dsa_ameth.c
crypto/stack/safestack.h
crypto/ui/ui.h

diff --git a/CHANGES b/CHANGES
index 41efec4..e672750 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,13 @@
 
  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.
      [Andy Polyakov]
 
index d2b8329..bb8992c 100644 (file)
@@ -518,12 +518,18 @@ typedef struct asn1_type_st
                 * contain the set or sequence bytes */
                ASN1_STRING *           set;
                ASN1_STRING *           sequence;
+               ASN1_VALUE *            asn1_value;
                } value;
        } ASN1_TYPE;
 
 DECLARE_STACK_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
        {
        ASN1_OCTET_STRING *header;
index e21c05e..a6cd1ad 100644 (file)
@@ -442,9 +442,9 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
        ASN1_TYPE *ret = NULL;
        STACK_OF(ASN1_TYPE) *sk = NULL;
        STACK_OF(CONF_VALUE) *sect = NULL;
-       unsigned char *der = NULL, *p;
+       unsigned char *der = NULL;
        int derlen;
-       int i, is_set;
+       int i;
        sk = sk_ASN1_TYPE_new_null();
        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 */
 
        if (utype == V_ASN1_SET)
-               is_set = 1;
+               derlen = i2d_ASN1_SET_ANY(sk, &der);
        else
-               is_set = 0;
-
-
-       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);
+               derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
 
        if (!(ret = ASN1_TYPE_new()))
                goto bad;
index 42e5a4e..e90cfa9 100644 (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
         * assumes the input is surrounded by an ASN1 SEQUENCE.
         */
-       inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, 
-                       ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+       inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
        /* Since we only need to discern "traditional format" RSA and DSA
         * keys we can just count the elements.
          */
index da91170..f3355e7 100644 (file)
@@ -106,7 +106,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt,
        }
 
        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)) {
                ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
                goto err;
index 3c1db8a..6724a3e 100644 (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(!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->type = V_ASN1_SEQUENCE;
 
@@ -204,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
 
        /* 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->type = V_ASN1_SEQUENCE;
 
index c32510f..61632a9 100644 (file)
@@ -114,6 +114,8 @@ unsigned long ASN1_tag2bit(int tag)
 /* Macro to initialize and invalidate the cache */
 
 #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 
  * like a standard 'd2i' function. 'in' points to 
@@ -130,7 +132,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
        ASN1_VALUE *ptmpval = NULL;
        if (!pval)
                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) 
                return *pval;
        return NULL;
@@ -140,7 +142,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
                const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
        {
        ASN1_TLC c;
-       asn1_tlc_clear(&c);
+       asn1_tlc_clear_nc(&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)
                        ASN1_TYPE_set(typ, utype, NULL);
                opval = pval;
-               pval = (ASN1_VALUE **)&typ->value.ptr;
+               pval = &typ->value.asn1_value;
                }
        switch(utype)
                {
index 685401e..28f6e42 100644 (file)
@@ -597,7 +597,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
                typ = (ASN1_TYPE *)*pval;
                utype = typ->type;
                *putype = utype;
-               pval = (ASN1_VALUE **)&typ->value.ptr;
+               pval = &typ->value.asn1_value;
                }
        else utype = *putype;
 
index 81b6ac8..43c00de 100644 (file)
@@ -221,7 +221,7 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
                {
                ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
                utype = typ->type;
-               pval = (ASN1_VALUE **)&typ->value.ptr;
+               pval = &typ->value.asn1_value;
                if (!*pval)
                        return;
                }
index cf4c4ab..d9f32bd 100644 (file)
@@ -533,7 +533,7 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
                {
                ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
                utype = atype->type;
-               fld = (ASN1_VALUE **)&atype->value.ptr;
+               fld = &atype->value.asn1_value;
                str = (ASN1_STRING *)*fld;
                if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
                        pname = NULL;
index 6f17f1b..ec96d48 100644 (file)
@@ -135,3 +135,14 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
 /* Special, OCTET STRING with indefinite length constructed support */
 
 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)
index 4c073dd..39f21b6 100644 (file)
@@ -79,8 +79,6 @@ typedef struct
        } CONF_VALUE;
 
 DECLARE_STACK_OF(CONF_VALUE)
-DECLARE_STACK_OF(CONF_MODULE)
-DECLARE_STACK_OF(CONF_IMODULE)
 
 struct conf_st;
 struct conf_method_st;
@@ -105,6 +103,9 @@ struct conf_method_st
 typedef struct conf_imodule_st CONF_IMODULE;
 typedef struct conf_module_st CONF_MODULE;
 
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
 /* DSO module function typedefs */
 typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
 typedef void conf_finish_func(CONF_IMODULE *md);
index b380991..d39833c 100644 (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))
                {
                ASN1_TYPE *t1, *t2;
-               if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pklen, 
-                                                         d2i_ASN1_TYPE,
-                                                         ASN1_TYPE_free)))
+               if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)));
                        goto decerr;
                if (sk_ASN1_TYPE_num(ndsa) != 2)
                        goto decerr;
index 5e55d15..2d3a2e9 100644 (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
  * modification, are permitted provided that the following conditions
 
 #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);
 #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))
 /* End of util/mkstack.pl block, you may now edit :-) */
 
+#endif
+
 #endif /* !defined HEADER_SAFESTACK_H */
index 0182964..c343595 100644 (file)
@@ -287,8 +287,8 @@ UI_METHOD *UI_OpenSSL(void);
 /* 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.
 */
-DECLARE_STACK_OF(UI_STRING)
 typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
 
 /* The different types of strings that are currently supported.
    This is only needed by method authors. */