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 a51168e..11ccdce 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 4f9f7f6..6c94696 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 5aa65e2..6f37810 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 01cf9e4..22041a8 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 58a1a9d..08fcb85 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 377caf9..02ec2d4 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 5482330..539b51f 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 c00f7d7..83909c1 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 6d8a891..e03f24a 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 12bd701..23447e8 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 8c32098..a3d85b1 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 eb1b7c6..9fbb0c8 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);