diff --git a/CHANGES b/CHANGES index a51168ef92..11ccdce558 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,14 @@ Changes between 1.0.0 and 1.1.0 [xx XXX xxxx] + *) Add algorithm specific signature printing. An individual ASN1 method + can now print out signatures instead of the standard hex dump. + + More complex signatures (e.g. PSS) can print out more meaningful + information. Include DSA version that prints out the signature + parameters r, s. + [Steve Henson] + *) Add -trusted_first option which attempts to find certificates in the trusted store even if an untrusted chain is also supplied. [Steve Henson] diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 4f9f7f605f..6c94696ae8 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -235,7 +235,7 @@ typedef struct asn1_object_st */ #define ASN1_STRING_FLAG_MSTRING 0x040 /* This is the base type that holds just about everything :-) */ -typedef struct asn1_string_st +struct asn1_string_st { int length; int type; @@ -245,7 +245,7 @@ typedef struct asn1_string_st * input data has a non-zero 'unused bits' value, it will be * handled correctly */ long flags; - } ASN1_STRING; + }; /* ASN1_ENCODING structure: this is used to save the received * encoding of an ASN1 type. This is useful to get round diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h index 5aa65e28f5..6f3781045d 100644 --- a/crypto/asn1/asn1_locl.h +++ b/crypto/asn1/asn1_locl.h @@ -102,6 +102,9 @@ struct evp_pkey_asn1_method_st int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + int (*sig_print)(BIO *out, + const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx); void (*pkey_free)(EVP_PKEY *pkey); int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c index 01cf9e427a..22041a8fc5 100644 --- a/crypto/asn1/t_x509.c +++ b/crypto/asn1/t_x509.c @@ -72,6 +72,7 @@ #include #include #include +#include "asn1_locl.h" #ifndef OPENSSL_NO_FP_API int X509_print_fp(FILE *fp, X509 *x) @@ -286,26 +287,48 @@ err: return(0); } -int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { - unsigned char *s; + const unsigned char *s; int i, n; - if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0; - if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0; n=sig->length; s=sig->data; for (i=0; ialgorithm) <= 0) return 0; + + sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid != NID_undef) + { + int pkey_nid, dig_nid; + const EVP_PKEY_ASN1_METHOD *ameth; + if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) + { + ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); + if (ameth && ameth->sig_print) + return ameth->sig_print(bp, sigalg, sig, 9, 0); + } + } + + return X509_signature_dump(bp, sig, 9); +} + int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) { int i,n; diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c index 58a1a9d02e..08fcb85f93 100644 --- a/crypto/cmac/cm_ameth.c +++ b/crypto/cmac/cm_ameth.c @@ -93,7 +93,7 @@ const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = cmac_size, 0, - 0,0,0,0,0,0, + 0,0,0,0,0,0,0, cmac_key_free, 0, diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index 377caf96c9..02ec2d47b4 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -493,6 +493,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = dh_copy_parameters, dh_cmp_parameters, dh_param_print, + 0, int_dh_free, 0 diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 5482330c84..539b51f951 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -542,6 +542,44 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); } +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx) + { + DSA_SIG *dsa_sig; + const unsigned char *p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig) + { + int rv = 0; + size_t buf_len = 0; + unsigned char *m=NULL; + update_buflen(dsa_sig->r, &buf_len); + update_buflen(dsa_sig->s, &buf_len); + m = OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BIO_write(bp, "\n", 1) != 1) + goto err; + + if (!ASN1_bn_print(bp,"r: ",dsa_sig->r,m,indent)) + goto err; + if (!ASN1_bn_print(bp,"s: ",dsa_sig->s,m,indent)) + goto err; + rv = 1; + err: + if (m) + OPENSSL_free(m); + DSA_SIG_free(dsa_sig); + return rv; + } + return X509_signature_dump(bp, sig, indent); + } + static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) @@ -647,6 +685,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = dsa_copy_parameters, dsa_cmp_parameters, dsa_param_print, + dsa_sig_print, int_dsa_free, dsa_pkey_ctrl, diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index c00f7d746c..83909c1853 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -651,6 +651,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = ec_copy_parameters, ec_cmp_parameters, eckey_param_print, + 0, int_ec_free, ec_pkey_ctrl, diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c index 6d8a89149e..e03f24aeda 100644 --- a/crypto/hmac/hm_ameth.c +++ b/crypto/hmac/hm_ameth.c @@ -153,7 +153,7 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = hmac_size, 0, - 0,0,0,0,0,0, + 0,0,0,0,0,0,0, hmac_key_free, hmac_pkey_ctrl, diff --git a/crypto/ossl_typ.h b/crypto/ossl_typ.h index 12bd7014de..23447e8284 100644 --- a/crypto/ossl_typ.h +++ b/crypto/ossl_typ.h @@ -91,6 +91,7 @@ typedef struct asn1_string_st ASN1_TIME; typedef struct asn1_string_st ASN1_GENERALIZEDTIME; typedef struct asn1_string_st ASN1_VISIBLESTRING; typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; typedef int ASN1_BOOLEAN; typedef int ASN1_NULL; #endif diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 8c3209885e..a3d85b1f44 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -333,7 +333,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = int_rsa_size, rsa_bits, - 0,0,0,0,0,0, + 0,0,0,0,0,0,0, int_rsa_free, rsa_pkey_ctrl, diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index eb1b7c6b2d..9fbb0c809d 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -656,6 +656,7 @@ int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); +int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent); int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig); int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);