Move CT viewer extension code to crypto/x509v3
[openssl.git] / crypto / x509v3 / v3_scts.c
index 0868a7b..c6ef0dc 100644 (file)
@@ -59,8 +59,8 @@
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
-#include "o_time.h"
 #include <openssl/x509v3.h>
 #include <openssl/x509v3.h>
+#include <openssl/bn.h>
 #include "../ssl/ssl_locl.h"
 
 static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct, BIO *out, int indent);
 #include "../ssl/ssl_locl.h"
 
 static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct, BIO *out, int indent);
@@ -79,95 +79,48 @@ NULL},
 NULL},
 };
 
 NULL},
 };
 
-
-/* <ripped>
- * from crypto/asn1/t_x509.c
- */
-static const char *mon[12]=
-    {
-    "Jan","Feb","Mar","Apr","May","Jun",
-    "Jul","Aug","Sep","Oct","Nov","Dec"
-    };
-/* </ripped> */
-
-
-/* <ripped>
- * from ssl/t1_lib.c
- */
-typedef struct 
+static void tls12_signature_print(BIO *out, const unsigned char *data)
        {
        {
-       int nid;
-       int id;
-       } tls12_lookup;
-
-static tls12_lookup tls12_md[] = {
-       {NID_md5, TLSEXT_hash_md5},
-       {NID_sha1, TLSEXT_hash_sha1},
-       {NID_sha224, TLSEXT_hash_sha224},
-       {NID_sha256, TLSEXT_hash_sha256},
-       {NID_sha384, TLSEXT_hash_sha384},
-       {NID_sha512, TLSEXT_hash_sha512}
-};
-
-static tls12_lookup tls12_sig[] = {
-       {EVP_PKEY_RSA, TLSEXT_signature_rsa},
-       {EVP_PKEY_DSA, TLSEXT_signature_dsa},
-       {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
-};
-
-static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
-       {
-       size_t i;
-       for (i = 0; i < tlen; i++)
+       int nid = NID_undef;
+       /* RFC6962 only permits two signature algorithms */
+       if (data[0] == TLSEXT_hash_sha256)
                {
                {
-               if ((table[i].id) == id)
-                       return table[i].nid;
+               if (data[1] == TLSEXT_signature_rsa)
+                       nid = NID_sha256WithRSAEncryption;
+               else if (data[1] == TLSEXT_signature_ecdsa)
+                       nid = NID_ecdsa_with_SHA256;
                }
                }
-       return NID_undef;
+       if (nid == NID_undef)
+               BIO_printf(out, "%02X%02X", data[0], data[1]);
+       else
+               BIO_printf(out, "%s", OBJ_nid2ln(nid));
        }
 
        }
 
-/* Convert TLS 1.2 signature algorithm extension values into NIDs */
-static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
-                       int *psignhash_nid, const unsigned char *data)
+static void timestamp_print(BIO *out, BN_ULLONG timestamp)
        {
        {
-       int sign_nid = 0, hash_nid = 0;
-       if (!phash_nid && !psign_nid && !psignhash_nid)
-               return;
-       if (phash_nid || psignhash_nid)
-               {
-               hash_nid = tls12_find_nid(data[0], tls12_md,
-                                       sizeof(tls12_md)/sizeof(tls12_lookup));
-               if (phash_nid)
-                       *phash_nid = hash_nid;
-               }
-       if (psign_nid || psignhash_nid)
-               {
-               sign_nid = tls12_find_nid(data[1], tls12_sig,
-                                       sizeof(tls12_sig)/sizeof(tls12_lookup));
-               if (psign_nid)
-                       *psign_nid = sign_nid;
-               }
-       if (psignhash_nid)
-               {
-               if (sign_nid && hash_nid)
-                       OBJ_find_sigid_by_algs(psignhash_nid,
-                                                       hash_nid, sign_nid);
-               else
-                       *psignhash_nid = NID_undef;
-               }
+       ASN1_GENERALIZEDTIME *gen;
+       char genstr[20];
+       gen = ASN1_GENERALIZEDTIME_new();
+       ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
+                                       timestamp / 86400000,
+                                       (timestamp % 86400000) / 1000);
+       /* Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
+        * characters long with a final Z. Update it with fractional seconds.
+        */
+       BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
+                               ASN1_STRING_data(gen),
+                               (unsigned int)(timestamp % 1000));
+       ASN1_GENERALIZEDTIME_set_string(gen, genstr);
+       ASN1_GENERALIZEDTIME_print(out, gen);
+       ASN1_GENERALIZEDTIME_free(gen);
        }
        }
-/* </ripped> */
-
 
 static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
 
 static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
-            BIO *out, int indent)
-{
+                      BIO *out, int indent)
+       {
        BN_ULLONG timestamp;
        unsigned char* data = oct->data;
        BN_ULLONG timestamp;
        unsigned char* data = oct->data;
-       unsigned short listlen, sctlen, fieldlen, linelen;
-       int signhash_nid;
-       time_t unix_epoch = 0;
-       struct tm tm1;
+       unsigned short listlen, sctlen = 0, fieldlen;
 
        if (oct->length < 2)
                return 0;
 
        if (oct->length < 2)
                return 0;
@@ -175,7 +128,8 @@ static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
        if (listlen != oct->length - 2)
                return 0;
 
        if (listlen != oct->length - 2)
                return 0;
 
-       while (listlen > 0) {
+       while (listlen > 0)
+               {
                if (listlen < 2)
                        return 0;
                n2s(data, sctlen);
                if (listlen < 2)
                        return 0;
                n2s(data, sctlen);
@@ -185,7 +139,11 @@ static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
                        return 0;
                listlen -= sctlen;
 
                        return 0;
                listlen -= sctlen;
 
-               if (*data == 0) {       /* v1 SCT */
+               BIO_printf(out, "%*sSigned Certificate Timestamp:", indent,
+                          "");
+
+               if (*data == 0)         /* SCT v1 */
+                       {
                        /* Fixed-length header:
                         *              struct {
                         * (1 byte)       Version sct_version;
                        /* Fixed-length header:
                         *              struct {
                         * (1 byte)       Version sct_version;
@@ -197,43 +155,28 @@ static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
                                return 0;
                        sctlen -= 43;
 
                                return 0;
                        sctlen -= 43;
 
-                       BIO_printf(out, "\n%*sVersion   : v1(0)", indent, "");
+                       BIO_printf(out, "\n%*sVersion   : v1(0)", indent + 4,
+                                  "");
 
 
-                       BIO_printf(out, "\n%*sLog ID    : ", indent, "");
-                       BIO_printf(out, "%s:", hex_to_string(data + 1, 16));
-                       BIO_printf(out, "\n%*s            ", indent, "");
-                       BIO_printf(out, "%s", hex_to_string(data + 17, 16));
+                       BIO_printf(out, "\n%*sLog ID    : ", indent + 4, "");
+                       BIO_hex_string(out, indent + 16, 16, data + 1, 32);
 
                        data += 33;
                        n2l8(data, timestamp);
 
                        data += 33;
                        n2l8(data, timestamp);
-                       OPENSSL_gmtime(&unix_epoch, &tm1);
-                       OPENSSL_gmtime_adj(&tm1, timestamp / 86400000,
-                                               (timestamp % 86400000) / 1000);
-                       BIO_printf(out, "\n%*sTimestamp : ", indent, "");
-                       BIO_printf(out, "%s %2d %02d:%02d:%02d.%03u %d UTC",
-                                  mon[tm1.tm_mon], tm1.tm_mday, tm1.tm_hour,
-                                  tm1.tm_min, tm1.tm_sec,
-                                  (unsigned int)(timestamp % 1000),
-                                  tm1.tm_year + 1900);
+                       BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
+                       timestamp_print(out, timestamp);
 
                        n2s(data, fieldlen);
                        if (sctlen < fieldlen)
                                return 0;
                        sctlen -= fieldlen;
 
                        n2s(data, fieldlen);
                        if (sctlen < fieldlen)
                                return 0;
                        sctlen -= fieldlen;
-                       BIO_printf(out, "\n%*sExtensions:", indent, "");
+                       BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
                        if (fieldlen == 0)
                        if (fieldlen == 0)
-                               BIO_printf(out, " none");
-                       for (linelen = 16; fieldlen > 0; ) {
-                               if (linelen > fieldlen)
-                                       linelen = fieldlen;
-                               BIO_printf(out, "\n%*s       ", indent, "");
-                               BIO_printf(out, "%s",
-                                          hex_to_string(data, linelen));
-                               if (fieldlen > 16)
-                                       BIO_printf(out, ":");
-                               data += linelen;
-                               fieldlen -= linelen;
-                       }
+                               BIO_printf(out, "none");
+                       else
+                               BIO_hex_string(out, indent + 16, 16, data,
+                                              fieldlen);
+                       data += fieldlen;
 
                        /* digitally-signed struct header:
                         * (1 byte) Hash algorithm
 
                        /* digitally-signed struct header:
                         * (1 byte) Hash algorithm
@@ -244,29 +187,18 @@ static int i2r_scts(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct,
                                return 0;
                        sctlen -= 4;
 
                                return 0;
                        sctlen -= 4;
 
-                       tls1_lookup_sigalg(NULL, NULL, &signhash_nid, data);
+                       BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
+                       tls12_signature_print(out, data);
                        data += 2;
                        n2s(data, fieldlen);
                        if (sctlen != fieldlen)
                                return 0;
                        data += 2;
                        n2s(data, fieldlen);
                        if (sctlen != fieldlen)
                                return 0;
-                       BIO_printf(out, "\n%*sSignature : ", indent, "");
-                       BIO_printf(out, "%s", OBJ_nid2ln(signhash_nid));
-                       for (linelen = 16; fieldlen > 0; ) {
-                               if (linelen > fieldlen)
-                                       linelen = fieldlen;
-                               BIO_printf(out, "\n%*s            ", indent,
-                                          "");
-                               BIO_printf(out, "%s",
-                                          hex_to_string(data, linelen));
-                               if (fieldlen > 16)
-                                       BIO_printf(out, ":");
-                               data += linelen;
-                               fieldlen -= linelen;
+                       BIO_printf(out, "\n%*s            ", indent + 4, "");
+                       BIO_hex_string(out, indent + 16, 16, data, fieldlen);
+                       if (listlen > 0) BIO_printf(out, "\n");
+                       data += fieldlen;
                        }
                        }
-
-                       BIO_printf(out, "\n");
                }
                }
-       }
 
        return 1;
 
        return 1;
-}
+       }