From 2e430277578d3dd586cd005682a54a59d6158146 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 15 Mar 2015 16:26:04 +0000 Subject: [PATCH] make ASN1_OBJECT opaque Reviewed-by: Matt Caswell --- crypto/asn1/a_object.c | 1 + crypto/asn1/asn1.h | 16 ---------------- crypto/asn1/asn_moid.c | 1 + crypto/asn1/tasn_enc.c | 1 + crypto/evp/evp_lib.c | 2 +- crypto/include/internal/asn1_int.h | 16 ++++++++++++++++ crypto/objects/obj_dat.c | 15 +++++++++++++++ crypto/objects/obj_lib.c | 1 + crypto/objects/objects.h | 3 +++ crypto/rsa/rsa_sign.c | 2 +- doc/crypto/OBJ_nid2obj.pod | 14 ++++++++++++++ engines/e_4758cca.c | 4 ++-- 12 files changed, 56 insertions(+), 20 deletions(-) diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index c780d8ee02..ddc3aaff7b 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -63,6 +63,7 @@ #include #include #include +#include "internal/asn1_int.h" int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) { diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index ef5b9e8d84..a00c08a965 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -194,22 +194,6 @@ typedef struct asn1_const_ctx_st { int line; /* used in error processing */ } ASN1_const_CTX; -/* - * These are used internally in the ASN1_OBJECT to keep track of whether the - * names and data need to be free()ed - */ -# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ -# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ -# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ -# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ -struct asn1_object_st { - const char *sn, *ln; - int nid; - int length; - const unsigned char *data; /* data remains const after init */ - int flags; /* Should we free this one */ -}; - # define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ /* * This indicates that the ASN1_STRING is not a real value but just a place diff --git a/crypto/asn1/asn_moid.c b/crypto/asn1/asn_moid.c index fab2dd92e2..da7e29119a 100644 --- a/crypto/asn1/asn_moid.c +++ b/crypto/asn1/asn_moid.c @@ -64,6 +64,7 @@ #include #include #include +#include "internal/asn1_int.h" /* Simple ASN1 OID module: add all objects in a given section */ diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index 1c200b0690..1d1f838078 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c @@ -63,6 +63,7 @@ #include #include #include +#include "internal/asn1_int.h" static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 966d9fb272..8d00029862 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -176,7 +176,7 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) default: /* Check it has an OID and it is valid */ otmp = OBJ_nid2obj(nid); - if (!otmp || !otmp->data) + if (OBJ_get0_data(otmp) == NULL) nid = NID_undef; ASN1_OBJECT_free(otmp); return nid; diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h index 58759bee6c..20c8f40511 100644 --- a/crypto/include/internal/asn1_int.h +++ b/crypto/include/internal/asn1_int.h @@ -103,3 +103,19 @@ struct evp_pkey_asn1_method_st { X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); } /* EVP_PKEY_ASN1_METHOD */ ; + +/* + * These are used internally in the ASN1_OBJECT to keep track of whether the + * names and data need to be free()ed + */ +# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ +# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ +# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ +# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ +struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +}; diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index e7366af8dc..5c861d1ec2 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -64,6 +64,7 @@ #include #include #include +#include "internal/asn1_int.h" /* obj_dat.h is generated from objects.h by obj_dat.pl */ #include "obj_dat.h" @@ -781,3 +782,17 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) OPENSSL_free(buf); return (ok); } + +size_t OBJ_length(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return 0; + return obj->length; +} + +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj) +{ + if (obj == NULL) + return NULL; + return obj->data; +} diff --git a/crypto/objects/obj_lib.c b/crypto/objects/obj_lib.c index 8851baffb2..0bcb5df506 100644 --- a/crypto/objects/obj_lib.c +++ b/crypto/objects/obj_lib.c @@ -61,6 +61,7 @@ #include #include #include +#include "internal/asn1_int.h" ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { diff --git a/crypto/objects/objects.h b/crypto/objects/objects.h index b8dafa89ce..165817fb1a 100644 --- a/crypto/objects/objects.h +++ b/crypto/objects/objects.h @@ -1107,6 +1107,9 @@ int OBJ_create(const char *oid, const char *sn, const char *ln); void OBJ_cleanup(void); int OBJ_create_objects(BIO *in); +size_t OBJ_length(const ASN1_OBJECT *obj); +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); int OBJ_add_sigid(int signid, int dig_id, int pkey_id); diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index cc45e40cc9..a521d1190a 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -95,7 +95,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); return (0); } - if (sig.algor->algorithm->length == 0) { + if (OBJ_length(sig.algor->algorithm) == 0) { RSAerr(RSA_F_RSA_SIGN, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return (0); diff --git a/doc/crypto/OBJ_nid2obj.pod b/doc/crypto/OBJ_nid2obj.pod index 1e45dd40f6..648204e4e7 100644 --- a/doc/crypto/OBJ_nid2obj.pod +++ b/doc/crypto/OBJ_nid2obj.pod @@ -29,6 +29,9 @@ functions int OBJ_create(const char *oid,const char *sn,const char *ln); void OBJ_cleanup(void); + size_t OBJ_length(const ASN1_OBJECT *obj); + const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + =head1 DESCRIPTION The ASN1 object utility functions process ASN1_OBJECT structures which are @@ -70,6 +73,11 @@ OBJ_cleanup() cleans up OpenSSLs internal object table: this should be called before an application exits if any new objects were added using OBJ_create(). +OBJ_length() returns the size of the content octets of B. + +OBJ_get0_data() returns a pointer to the content octets of B. +The returned pointer is an internal pointer which B be freed. + =head1 NOTES Objects in OpenSSL can have a short name, a long name and a numerical @@ -96,6 +104,12 @@ Objects do not need to be in the internal tables to be processed, the functions OBJ_txt2obj() and OBJ_obj2txt() can process the numerical form of an OID. +Some objects are used to reprsent algorithms which do not have a +corresponding ASN.1 OBJECT IDENTIFIER encoding (for example no OID currently +exists for a particular algorithm). As a result they B be encoded or +decoded as part of ASN.1 structures. Applications can determine if there +is a corresponding OBJECT IDENTIFIER by checking OBJ_length() is not zero. + =head1 EXAMPLES Create an object for B: diff --git a/engines/e_4758cca.c b/engines/e_4758cca.c index 5f771986cf..3b593c79c5 100644 --- a/engines/e_4758cca.c +++ b/engines/e_4758cca.c @@ -641,7 +641,7 @@ static int cca_rsa_verify(int type, const unsigned char *m, return 0; } - if (!algorithm.algorithm->length) { + if (!OBJ_length(algorithm.algorithm)) { CCA4758err(CCA4758_F_CCA_RSA_VERIFY, CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); return 0; @@ -754,7 +754,7 @@ static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, return 0; } - if (!algorithm.algorithm->length) { + if (!OBJ_length(algorithm.algorithm)) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); return 0; -- 2.25.1