Add algorithm specific signature printing. An individual ASN1 method can
authorDr. Stephen Henson <steve@openssl.org>
Sat, 6 Mar 2010 18:05:05 +0000 (18:05 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 6 Mar 2010 18:05:05 +0000 (18:05 +0000)
now print out signatures instead of the standard hex dump.

More complex signatures (e.g. PSS) can print out more meaningful information.

Sample DSA version included that prints out the signature parameters r, s.

[Note EVP_PKEY_ASN1_METHOD is an application opaque structure so adding
 new fields in the middle has no compatibility issues]

12 files changed:
CHANGES
crypto/asn1/asn1.h
crypto/asn1/asn1_locl.h
crypto/asn1/t_x509.c
crypto/cmac/cm_ameth.c
crypto/dh/dh_ameth.c
crypto/dsa/dsa_ameth.c
crypto/ec/ec_ameth.c
crypto/hmac/hm_ameth.c
crypto/ossl_typ.h
crypto/rsa/rsa_ameth.c
crypto/x509/x509.h

diff --git a/CHANGES b/CHANGES
index a51168ef92e56cf1bc41c2fc00562e2e549787dd..11ccdce55849fa12e643aac96f9b03da7182ba27 100644 (file)
--- 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]
index 4f9f7f605fda301b4832421642489bc605c406b0..6c94696ae8304d62927f0fe0e85535b7d2d13178 100644 (file)
@@ -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
index 5aa65e28f5f5cc241d9ec6394b2f2a0fc0c0b447..6f3781045dfcb4be0cb70d5be654da7f161ec067 100644 (file)
@@ -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);
index 01cf9e427a14233929aeb0c8a1488f873344a4ab..22041a8fc5c5926bf7642ff8d70536871a1dbc80 100644 (file)
@@ -72,6 +72,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
+#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; i<n; i++)
                {
                if ((i%18) == 0)
-                       if (BIO_write(bp,"\n        ",9) <= 0) return 0;
+                       if (BIO_write(bp,"\n",1) <= 0) return 0;
+                       if (BIO_indent(bp, indent, indent) <= 0) return 0;
                        if (BIO_printf(bp,"%02x%s",s[i],
                                ((i+1) == n)?"":":") <= 0) return 0;
                }
        if (BIO_write(bp,"\n",1) != 1) return 0;
+
        return 1;
 }
 
+int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+       int sig_nid;
+       if (BIO_puts(bp,"    Signature Algorithm: ") <= 0) return 0;
+       if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 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;
index 58a1a9d02e7eb8b49c5f0297e6a71230833becd1..08fcb85f9397149eb81682405b9fa8b00d17efeb 100644 (file)
@@ -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,
index 377caf96c930df8ee497d8c660aa9a26d0db3b9d..02ec2d47b4bd39998fa2278f727c085403aa9e8e 100644 (file)
@@ -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
index 5482330c84ded5b47aeb24e21dcd7a9019465231..539b51f95162f7e22b26107ea82ada548a07f2d4 100644 (file)
@@ -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,
index c00f7d746c36e293a451a5aed64b144aef54c315..83909c185359a73046952b2ad9ac38991211b2e7 100644 (file)
@@ -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,
index 6d8a89149ee3290cf6e9a00c7f76e5391d4c0446..e03f24aedab983b26fb4eb995fdf5ae511c69449 100644 (file)
@@ -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,
index 12bd7014de36b32e65bcff9f208d814f8ac50ea0..23447e8284619f43dcd564a0be34de214bff6de6 100644 (file)
@@ -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
index 8c3209885eab2f1bf3f4c18d3c5e06cf00cacfa2..a3d85b1f44d1cac50a31cc122681a903a66f88df 100644 (file)
@@ -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,
index eb1b7c6b2d34a8cf14b751f9688e73510f0f2245..9fbb0c809d2463384ae7ffc95429c28ba6fbc980 100644 (file)
@@ -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);