openssl: cert hash backports
authorGrazvydas Ignotas <notasas@gmail.com>
Sun, 26 Jul 2015 19:16:06 +0000 (22:16 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 26 Jul 2015 19:16:06 +0000 (22:16 +0300)
needed to be able to create hash symlinks in /etc/ssl/certs
(run by ca-certificates) that newer openssl wants

recipes/openssl/openssl-0.9.8zg/0001-Store-canonical-encodings-of-Name-structures.patch [new file with mode: 0644]
recipes/openssl/openssl-0.9.8zg/0002-canonical-related-backports-from-1.0.0s.patch [new file with mode: 0644]
recipes/openssl/openssl-0.9.8zg/0003-Update-certificate-hash-line-format-to-handle-canoni.patch [new file with mode: 0644]
recipes/openssl/openssl-0.9.8zg/0004-PR-2136-Submitted-by-Willy-Weisz-weisz-vcpc.univie.a.patch [new file with mode: 0644]
recipes/openssl/openssl-0.9.8zg/c_rehash-compat.patch [new file with mode: 0644]
recipes/openssl/openssl-0.9.8zg/debian/rehash-crt.patch
recipes/openssl/openssl_0.9.8zg.bb

diff --git a/recipes/openssl/openssl-0.9.8zg/0001-Store-canonical-encodings-of-Name-structures.patch b/recipes/openssl/openssl-0.9.8zg/0001-Store-canonical-encodings-of-Name-structures.patch
new file mode 100644 (file)
index 0000000..c3c5cb1
--- /dev/null
@@ -0,0 +1,289 @@
+From ad5a56490ee8a14777c051c90ffe6d38401997bd Mon Sep 17 00:00:00 2001
+From: "Dr. Stephen Henson" <steve@openssl.org>
+Date: Tue, 18 Jul 2006 12:36:19 +0000
+Subject: [PATCH 1/4] Store canonical encodings of Name structures.
+
+---
+ crypto/asn1/x_name.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ crypto/x509/x509.h   |   2 +
+ 2 files changed, 202 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c
+index 85be1a6..82ad1f0 100644
+--- a/crypto/asn1/x_name.c
++++ b/crypto/asn1/x_name.c
+@@ -57,6 +57,7 @@
+  */
+ #include <stdio.h>
++#include <ctype.h>
+ #include "cryptlib.h"
+ #include <openssl/asn1t.h>
+ #include <openssl/x509.h>
+@@ -71,6 +72,9 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+ static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
+ static int x509_name_encode(X509_NAME *a);
++static int x509_name_canon(X509_NAME *a);
++static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
++static int i2d_name_canon(STACK *intname, unsigned char **in);
+ ASN1_SEQUENCE(X509_NAME_ENTRY) = {
+         ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+@@ -125,6 +129,8 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+         goto memerr;
+     if ((ret->bytes = BUF_MEM_new()) == NULL)
+         goto memerr;
++    ret->canon_enc = NULL;
++    ret->canon_enclen = 0;
+     ret->modified = 1;
+     *val = (ASN1_VALUE *)ret;
+     return 1;
+@@ -148,6 +154,8 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+     BUF_MEM_free(a->bytes);
+     sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
++    if (a->canon_enc)
++        OPENSSL_free(a->canon_enc);
+     OPENSSL_free(a);
+     *pval = NULL;
+ }
+@@ -163,6 +171,11 @@ static void sk_internal_free(void *a)
+     sk_free(a);
+ }
++static void canon_free(void *a)
++{
++      sk_X509_NAME_ENTRY_pop_free(a, X509_NAME_ENTRY_free);
++}
++
+ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
+                             long len, const ASN1_ITEM *it, int tag,
+                             int aclass, char opt, ASN1_TLC *ctx)
+@@ -214,6 +227,9 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
+         sk_X509_NAME_ENTRY_free(entries);
+     }
+     sk_free(intname.s);
++    ret = x509_name_canon(nm.x);
++    if (!ret)
++        goto err;
+     nm.x->modified = 0;
+     *val = nm.a;
+     *in = p;
+@@ -231,9 +247,12 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+     int ret;
+     X509_NAME *a = (X509_NAME *)*val;
+     if (a->modified) {
+-        ret = x509_name_encode((X509_NAME *)a);
++        ret = x509_name_encode(a);
+         if (ret < 0)
+             return ret;
++        ret = x509_name_canon(a);
++        if(ret < 0)
++            return ret;
+     }
+     ret = a->bytes->length;
+     if (out != NULL) {
+@@ -288,6 +307,186 @@ static int x509_name_encode(X509_NAME *a)
+     return -1;
+ }
++/* This function generates the canonical encoding of the Name structure.
++ * In it all strings are converted to UTF8, leading, trailing and
++ * multiple spaces collapsed, converted to lower case and the leading
++ * SEQUENCE header removed.
++ *
++ * In future we could also normalize the UTF8 too.
++ *
++ * By doing this comparison of Name structures can be rapidly
++ * perfomed by just using memcmp() of the canonical encoding.
++ * By omitting the leading SEQUENCE name constraints of type
++ * dirName can also be checked with a simple memcmp().
++ */
++
++static int x509_name_canon(X509_NAME *a)
++      {
++      unsigned char *p;
++      STACK *intname = NULL;
++      STACK_OF(X509_NAME_ENTRY) *entries = NULL;
++      X509_NAME_ENTRY *entry, *tmpentry;
++      int i, set = -1, ret = 0;
++      if (a->canon_enc)
++              {
++              OPENSSL_free(a->canon_enc);
++              a->canon_enc = NULL;
++              }
++      intname = sk_new_null();
++      if(!intname)
++              goto err;
++      for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
++              {
++              entry = sk_X509_NAME_ENTRY_value(a->entries, i);
++              if(entry->set != set)
++                      {
++                      entries = sk_X509_NAME_ENTRY_new_null();
++                      if(!entries)
++                              goto err;
++                      if(!sk_push(intname, (char *)entries))
++                              goto err;
++                      set = entry->set;
++                      }
++              tmpentry = X509_NAME_ENTRY_new();
++              tmpentry->object = OBJ_dup(entry->object);
++              if (!asn1_string_canon(tmpentry->value, entry->value))
++                      goto err;
++              if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
++                      goto err;
++              tmpentry = NULL;
++              }
++
++      /* Finally generate encoding */
++
++      a->canon_enclen = i2d_name_canon(intname, NULL);
++
++      p = OPENSSL_malloc(a->canon_enclen);
++
++      if (!p)
++              goto err;
++
++      a->canon_enc = p;
++
++      i2d_name_canon(intname, &p);
++
++      ret = 1;
++
++      err:
++
++      if (tmpentry)
++              X509_NAME_ENTRY_free(tmpentry);
++      if (intname)
++              sk_pop_free(intname, canon_free);
++      return ret;
++      }
++
++/* Bitmap of all the types of string that will be canonicalized. */
++
++#define ASN1_MASK_CANON       \
++      (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
++      | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
++      | B_ASN1_VISIBLESTRING)
++      
++
++static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
++      {
++      unsigned char *to, *from;
++      int len, i;
++
++      /* If type not in bitmask just copy string across */
++      if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
++              {
++              out->type = in->type;
++              if (!ASN1_STRING_set(out, in->data, in->length))
++                      return 0;
++              }
++
++      out->type = V_ASN1_UTF8STRING;
++      out->length = ASN1_STRING_to_UTF8(&out->data, in);
++      if (out->length == -1)
++              return 0;
++
++      to = out->data;
++      from = to;
++
++      len = out->length;
++
++      /* Convert string in place to canonical form.
++       * Ultimately we may need to handle a wider range of characters
++       * but for now ignore anything with MSB set and rely on the
++       * isspace() and tolower() functions.
++       */
++
++      /* Ignore leading spaces */
++      while((len > 0) && !(*from & 0x80) && isspace(*from))
++              {
++              from++;
++              len--;
++              }
++
++      to = from + len - 1;
++
++      /* Ignore trailing spaces */
++      while ((len > 0) && !(*to & 0x80) && isspace(*to))
++              {
++              to--;
++              len--;
++              }
++
++      to = out->data;
++
++      i = 0;
++      while(i < len)
++              {
++              /* If MSB set just copy across */
++              if (*from & 0x80)
++                      *to++ = *from++;
++              /* Collapse multiple spaces */
++              else if (isspace(*from))
++                      {
++                      /* Copy one space across */
++                      *to++ = ' ';
++                      /* Ignore subsequent spaces. Note: don't need to
++                       * check len here because we know the last 
++                       * character is a non-space so we can't overflow.
++                       */
++                      do
++                              {
++                              from++;
++                              i++;
++                              }
++                      while(!(*from & 0x80) && isspace(*from));
++                      }
++              else
++                      {
++                      *to++ = tolower(*from++);
++                      i++;
++                      }
++              }
++
++      out->length = to - out->data;
++
++      return 1;
++
++      }
++
++static int i2d_name_canon(STACK *intname, unsigned char **in)
++      {
++      int i, len, ltmp;
++      ASN1_VALUE *v;
++      len = 0;
++      for (i = 0; i < sk_num(intname); i++)
++              {
++              v = (ASN1_VALUE *)sk_value(intname, i);
++              ltmp = ASN1_item_ex_i2d(&v, in,
++                      ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
++              if (ltmp < 0)
++                      return ltmp;
++              len += ltmp;
++              }
++      return len;
++      }
++
+ int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+ {
+     X509_NAME *in;
+diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
+index 51cccbf..76efbd8 100644
+--- a/crypto/x509/x509.h
++++ b/crypto/x509/x509.h
+@@ -185,6 +185,8 @@ struct X509_name_st {
+     char *bytes;
+ # endif
+     unsigned long hash;         /* Keep the hash around for lookups */
++    unsigned char *canon_enc;
++    int canon_enclen;
+ } /* X509_NAME */ ;
+ DECLARE_STACK_OF(X509_NAME)
+-- 
+1.9.1
+
diff --git a/recipes/openssl/openssl-0.9.8zg/0002-canonical-related-backports-from-1.0.0s.patch b/recipes/openssl/openssl-0.9.8zg/0002-canonical-related-backports-from-1.0.0s.patch
new file mode 100644 (file)
index 0000000..6d6c46e
--- /dev/null
@@ -0,0 +1,370 @@
+From 2ddc9de2d172c818b366153c764383d8ff00fefa Mon Sep 17 00:00:00 2001
+From: notaz <notasas@gmail.com>
+Date: Sun, 26 Jul 2015 21:09:38 +0300
+Subject: [PATCH 2/4] canonical related backports from 1.0.0s
+
+---
+ crypto/asn1/x_name.c | 339 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 168 insertions(+), 171 deletions(-)
+
+diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c
+index 82ad1f0..5fa51bd 100644
+--- a/crypto/asn1/x_name.c
++++ b/crypto/asn1/x_name.c
+@@ -307,185 +307,182 @@ static int x509_name_encode(X509_NAME *a)
+     return -1;
+ }
+-/* This function generates the canonical encoding of the Name structure.
+- * In it all strings are converted to UTF8, leading, trailing and
+- * multiple spaces collapsed, converted to lower case and the leading
+- * SEQUENCE header removed.
+- *
+- * In future we could also normalize the UTF8 too.
+- *
+- * By doing this comparison of Name structures can be rapidly
+- * perfomed by just using memcmp() of the canonical encoding.
+- * By omitting the leading SEQUENCE name constraints of type
+- * dirName can also be checked with a simple memcmp().
++/*
++ * This function generates the canonical encoding of the Name structure. In
++ * it all strings are converted to UTF8, leading, trailing and multiple
++ * spaces collapsed, converted to lower case and the leading SEQUENCE header
++ * removed. In future we could also normalize the UTF8 too. By doing this
++ * comparison of Name structures can be rapidly perfomed by just using
++ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
++ * constraints of type dirName can also be checked with a simple memcmp().
+  */
+ static int x509_name_canon(X509_NAME *a)
+-      {
+-      unsigned char *p;
+-      STACK *intname = NULL;
+-      STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+-      X509_NAME_ENTRY *entry, *tmpentry;
+-      int i, set = -1, ret = 0;
+-      if (a->canon_enc)
+-              {
+-              OPENSSL_free(a->canon_enc);
+-              a->canon_enc = NULL;
+-              }
+-      intname = sk_new_null();
+-      if(!intname)
+-              goto err;
+-      for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
+-              {
+-              entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+-              if(entry->set != set)
+-                      {
+-                      entries = sk_X509_NAME_ENTRY_new_null();
+-                      if(!entries)
+-                              goto err;
+-                      if(!sk_push(intname, (char *)entries))
+-                              goto err;
+-                      set = entry->set;
+-                      }
+-              tmpentry = X509_NAME_ENTRY_new();
+-              tmpentry->object = OBJ_dup(entry->object);
+-              if (!asn1_string_canon(tmpentry->value, entry->value))
+-                      goto err;
+-              if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+-                      goto err;
+-              tmpentry = NULL;
+-              }
+-
+-      /* Finally generate encoding */
+-
+-      a->canon_enclen = i2d_name_canon(intname, NULL);
+-
+-      p = OPENSSL_malloc(a->canon_enclen);
+-
+-      if (!p)
+-              goto err;
+-
+-      a->canon_enc = p;
+-
+-      i2d_name_canon(intname, &p);
+-
+-      ret = 1;
+-
+-      err:
+-
+-      if (tmpentry)
+-              X509_NAME_ENTRY_free(tmpentry);
+-      if (intname)
+-              sk_pop_free(intname, canon_free);
+-      return ret;
+-      }
++{
++    unsigned char *p;
++    STACK *intname = NULL;
++    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
++    X509_NAME_ENTRY *entry, *tmpentry = NULL;
++    int i, set = -1, ret = 0;
++
++    if (a->canon_enc) {
++        OPENSSL_free(a->canon_enc);
++        a->canon_enc = NULL;
++    }
++    /* Special case: empty X509_NAME => null encoding */
++    if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
++        a->canon_enclen = 0;
++        return 1;
++    }
++    intname = sk_new_null();
++    if (!intname)
++        goto err;
++    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
++        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
++        if (entry->set != set) {
++            entries = sk_X509_NAME_ENTRY_new_null();
++            if (!entries)
++                goto err;
++            if (!sk_push(intname, (char *)entries))
++                goto err;
++            set = entry->set;
++        }
++        tmpentry = X509_NAME_ENTRY_new();
++        tmpentry->object = OBJ_dup(entry->object);
++        if (!asn1_string_canon(tmpentry->value, entry->value))
++            goto err;
++        if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
++            goto err;
++        tmpentry = NULL;
++    }
++
++    /* Finally generate encoding */
++
++    a->canon_enclen = i2d_name_canon(intname, NULL);
++
++    p = OPENSSL_malloc(a->canon_enclen);
++
++    if (!p)
++        goto err;
++
++    a->canon_enc = p;
++
++    i2d_name_canon(intname, &p);
++
++    ret = 1;
++
++ err:
++
++    if (tmpentry)
++        X509_NAME_ENTRY_free(tmpentry);
++    if (intname)
++        sk_pop_free(intname, canon_free);
++    return ret;
++}
+ /* Bitmap of all the types of string that will be canonicalized. */
+-#define ASN1_MASK_CANON       \
+-      (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+-      | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+-      | B_ASN1_VISIBLESTRING)
+-      
++#define ASN1_MASK_CANON \
++        (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
++        | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
++        | B_ASN1_VISIBLESTRING)
+ static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
+-      {
+-      unsigned char *to, *from;
+-      int len, i;
+-
+-      /* If type not in bitmask just copy string across */
+-      if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
+-              {
+-              out->type = in->type;
+-              if (!ASN1_STRING_set(out, in->data, in->length))
+-                      return 0;
+-              }
+-
+-      out->type = V_ASN1_UTF8STRING;
+-      out->length = ASN1_STRING_to_UTF8(&out->data, in);
+-      if (out->length == -1)
+-              return 0;
+-
+-      to = out->data;
+-      from = to;
+-
+-      len = out->length;
+-
+-      /* Convert string in place to canonical form.
+-       * Ultimately we may need to handle a wider range of characters
+-       * but for now ignore anything with MSB set and rely on the
+-       * isspace() and tolower() functions.
+-       */
+-
+-      /* Ignore leading spaces */
+-      while((len > 0) && !(*from & 0x80) && isspace(*from))
+-              {
+-              from++;
+-              len--;
+-              }
+-
+-      to = from + len - 1;
+-
+-      /* Ignore trailing spaces */
+-      while ((len > 0) && !(*to & 0x80) && isspace(*to))
+-              {
+-              to--;
+-              len--;
+-              }
+-
+-      to = out->data;
+-
+-      i = 0;
+-      while(i < len)
+-              {
+-              /* If MSB set just copy across */
+-              if (*from & 0x80)
+-                      *to++ = *from++;
+-              /* Collapse multiple spaces */
+-              else if (isspace(*from))
+-                      {
+-                      /* Copy one space across */
+-                      *to++ = ' ';
+-                      /* Ignore subsequent spaces. Note: don't need to
+-                       * check len here because we know the last 
+-                       * character is a non-space so we can't overflow.
+-                       */
+-                      do
+-                              {
+-                              from++;
+-                              i++;
+-                              }
+-                      while(!(*from & 0x80) && isspace(*from));
+-                      }
+-              else
+-                      {
+-                      *to++ = tolower(*from++);
+-                      i++;
+-                      }
+-              }
+-
+-      out->length = to - out->data;
+-
+-      return 1;
+-
+-      }
+-
+-static int i2d_name_canon(STACK *intname, unsigned char **in)
+-      {
+-      int i, len, ltmp;
+-      ASN1_VALUE *v;
+-      len = 0;
+-      for (i = 0; i < sk_num(intname); i++)
+-              {
+-              v = (ASN1_VALUE *)sk_value(intname, i);
+-              ltmp = ASN1_item_ex_i2d(&v, in,
+-                      ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+-              if (ltmp < 0)
+-                      return ltmp;
+-              len += ltmp;
+-              }
+-      return len;
+-      }
++{
++    unsigned char *to, *from;
++    int len, i;
++
++    /* If type not in bitmask just copy string across */
++    if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
++        if (!ASN1_STRING_set(out, in->data, in->length))
++            return 0;
++        return 1;
++    }
++
++    out->type = V_ASN1_UTF8STRING;
++    out->length = ASN1_STRING_to_UTF8(&out->data, in);
++    if (out->length == -1)
++        return 0;
++
++    to = out->data;
++    from = to;
++
++    len = out->length;
++
++    /*
++     * Convert string in place to canonical form. Ultimately we may need to
++     * handle a wider range of characters but for now ignore anything with
++     * MSB set and rely on the isspace() and tolower() functions.
++     */
++
++    /* Ignore leading spaces */
++    while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
++        from++;
++        len--;
++    }
++
++    to = from + len - 1;
++
++    /* Ignore trailing spaces */
++    while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
++        to--;
++        len--;
++    }
++
++    to = out->data;
++
++    i = 0;
++    while (i < len) {
++        /* If MSB set just copy across */
++        if (*from & 0x80) {
++            *to++ = *from++;
++            i++;
++        }
++        /* Collapse multiple spaces */
++        else if (isspace(*from)) {
++            /* Copy one space across */
++            *to++ = ' ';
++            /*
++             * Ignore subsequent spaces. Note: don't need to check len here
++             * because we know the last character is a non-space so we can't
++             * overflow.
++             */
++            do {
++                from++;
++                i++;
++            }
++            while (!(*from & 0x80) && isspace(*from));
++        } else {
++            *to++ = tolower(*from);
++            from++;
++            i++;
++        }
++    }
++
++    out->length = to - out->data;
++
++    return 1;
++
++}
++
++static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
++                          unsigned char **in)
++{
++    int i, len, ltmp;
++    ASN1_VALUE *v;
++    STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
++
++    len = 0;
++    for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
++        v = sk_ASN1_VALUE_value(intname, i);
++        ltmp = ASN1_item_ex_i2d(&v, in,
++                                ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
++        if (ltmp < 0)
++            return ltmp;
++        len += ltmp;
++    }
++    return len;
++}
+ int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+ {
+-- 
+1.9.1
+
diff --git a/recipes/openssl/openssl-0.9.8zg/0003-Update-certificate-hash-line-format-to-handle-canoni.patch b/recipes/openssl/openssl-0.9.8zg/0003-Update-certificate-hash-line-format-to-handle-canoni.patch
new file mode 100644 (file)
index 0000000..fd33171
--- /dev/null
@@ -0,0 +1,59 @@
+From 77649551e11dfe9f7d6dc5154abc4d1ab59726e2 Mon Sep 17 00:00:00 2001
+From: "Dr. Stephen Henson" <steve@openssl.org>
+Date: Thu, 15 Jan 2009 13:22:39 +0000
+Subject: [PATCH 3/4] Update certificate hash line format to handle canonical
+ format and avoid MD5 dependency.
+
+---
+ crypto/x509/x509.h     |  1 +
+ crypto/x509/x509_cmp.c | 17 ++++++++++++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
+index 76efbd8..2f8d271 100644
+--- a/crypto/x509/x509.h
++++ b/crypto/x509/x509.h
+@@ -1051,6 +1051,7 @@ unsigned long X509_subject_name_hash(X509 *x);
+ int X509_cmp(const X509 *a, const X509 *b);
+ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+ unsigned long X509_NAME_hash(X509_NAME *x);
++unsigned long X509_NAME_hash_old(X509_NAME *x);
+ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+ # ifndef OPENSSL_NO_FP_API
+diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
+index de66d37..150146e 100644
+--- a/crypto/x509/x509_cmp.c
++++ b/crypto/x509/x509_cmp.c
+@@ -310,12 +310,27 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
+     return (0);
+ }
++unsigned long X509_NAME_hash(X509_NAME *x)
++{
++      unsigned long ret=0;
++      unsigned char md[16];
++
++      /* Make sure X509_NAME structure contains valid cached encoding */
++      i2d_X509_NAME(x,NULL);
++      EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
++
++      ret=(   ((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
++              ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
++              )&0xffffffffL;
++      return(ret);
++}
++
+ #ifndef OPENSSL_NO_MD5
+ /*
+  * I now DER encode the name and hash it.  Since I cache the DER encoding,
+  * this is reasonably efficient.
+  */
+-unsigned long X509_NAME_hash(X509_NAME *x)
++unsigned long X509_NAME_hash_old(X509_NAME *x)
+ {
+     unsigned long ret = 0;
+     unsigned char md[16];
+-- 
+1.9.1
+
diff --git a/recipes/openssl/openssl-0.9.8zg/0004-PR-2136-Submitted-by-Willy-Weisz-weisz-vcpc.univie.a.patch b/recipes/openssl/openssl-0.9.8zg/0004-PR-2136-Submitted-by-Willy-Weisz-weisz-vcpc.univie.a.patch
new file mode 100644 (file)
index 0000000..f2dc3f8
--- /dev/null
@@ -0,0 +1,160 @@
+From 8fff84a70d9b61e511c5ce9927f8bfbdc26f4df3 Mon Sep 17 00:00:00 2001
+From: "Dr. Stephen Henson" <steve@openssl.org>
+Date: Tue, 12 Jan 2010 17:29:34 +0000
+Subject: [PATCH 4/4] PR: 2136 Submitted by: Willy Weisz
+ <weisz@vcpc.univie.ac.at>
+
+Add options to output hash using older algorithm compatible with OpenSSL
+versions before 1.0.0
+---
+ apps/x509.c            | 25 +++++++++++++++++++++++++
+ crypto/x509/x509.h     |  5 +++++
+ crypto/x509/x509_cmp.c | 14 ++++++++++++++
+ doc/apps/x509.pod      | 16 ++++++++++++++++
+ 4 files changed, 60 insertions(+)
+
+diff --git a/apps/x509.c b/apps/x509.c
+index d23f071..af49981 100644
+--- a/apps/x509.c
++++ b/apps/x509.c
+@@ -99,7 +99,13 @@ static const char *x509_usage[] = {
+     " -passin arg     - private key password source\n",
+     " -serial         - print serial number value\n",
+     " -subject_hash   - print subject hash value\n",
++#ifndef OPENSSL_NO_MD5
++    " -subject_hash_old   - print old-style (MD5) subject hash value\n",
++#endif
+     " -issuer_hash    - print issuer hash value\n",
++#ifndef OPENSSL_NO_MD5
++    " -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
++#endif
+     " -hash           - synonym for -subject_hash\n",
+     " -subject        - print subject DN\n",
+     " -issuer         - print issuer DN\n",
+@@ -180,6 +186,9 @@ int MAIN(int argc, char **argv)
+         0, enddate = 0;
+     int next_serial = 0;
+     int subject_hash = 0, issuer_hash = 0, ocspid = 0;
++#ifndef OPENSSL_NO_MD5
++    int subject_hash_old=0,issuer_hash_old=0;
++#endif
+     int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
+     int ocsp_uri = 0;
+     int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
+@@ -376,8 +385,16 @@ int MAIN(int argc, char **argv)
+         else if (strcmp(*argv, "-hash") == 0
+                  || strcmp(*argv, "-subject_hash") == 0)
+             subject_hash = ++num;
++#ifndef OPENSSL_NO_MD5
++        else if (strcmp(*argv,"-subject_hash_old") == 0)
++            subject_hash_old= ++num;
++#endif
+         else if (strcmp(*argv, "-issuer_hash") == 0)
+             issuer_hash = ++num;
++#ifndef OPENSSL_NO_MD5
++        else if (strcmp(*argv,"-issuer_hash_old") == 0)
++            issuer_hash_old= ++num;
++#endif
+         else if (strcmp(*argv, "-subject") == 0)
+             subject = ++num;
+         else if (strcmp(*argv, "-issuer") == 0)
+@@ -687,8 +704,16 @@ int MAIN(int argc, char **argv)
+                     BIO_puts(STDout, "<No Alias>\n");
+             } else if (subject_hash == i) {
+                 BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
++#ifndef OPENSSL_NO_MD5
++            } else if (subject_hash_old == i) {
++                BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
++#endif
+             } else if (issuer_hash == i) {
+                 BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
++#ifndef OPENSSL_NO_MD5
++            } else if (issuer_hash_old == i) {
++                BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
++#endif
+             } else if (pprint == i) {
+                 X509_PURPOSE *ptmp;
+                 int j;
+diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
+index 2f8d271..7ac4dbe 100644
+--- a/crypto/x509/x509.h
++++ b/crypto/x509/x509.h
+@@ -1048,6 +1048,11 @@ unsigned long X509_issuer_name_hash(X509 *a);
+ int X509_subject_name_cmp(const X509 *a, const X509 *b);
+ unsigned long X509_subject_name_hash(X509 *x);
++#ifndef OPENSSL_NO_MD5
++unsigned long X509_issuer_name_hash_old(X509 *a);
++unsigned long X509_subject_name_hash_old(X509 *x);
++#endif
++
+ int X509_cmp(const X509 *a, const X509 *b);
+ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+ unsigned long X509_NAME_hash(X509_NAME *x);
+diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
+index 150146e..8c587f9 100644
+--- a/crypto/x509/x509_cmp.c
++++ b/crypto/x509/x509_cmp.c
+@@ -127,6 +127,13 @@ unsigned long X509_issuer_name_hash(X509 *x)
+     return (X509_NAME_hash(x->cert_info->issuer));
+ }
++#ifndef OPENSSL_NO_MD5
++unsigned long X509_issuer_name_hash_old(X509 *x)
++      {
++      return(X509_NAME_hash_old(x->cert_info->issuer));
++      }
++#endif
++
+ X509_NAME *X509_get_subject_name(X509 *a)
+ {
+     return (a->cert_info->subject);
+@@ -142,6 +149,13 @@ unsigned long X509_subject_name_hash(X509 *x)
+     return (X509_NAME_hash(x->cert_info->subject));
+ }
++#ifndef OPENSSL_NO_MD5
++unsigned long X509_subject_name_hash_old(X509 *x)
++      {
++      return(X509_NAME_hash_old(x->cert_info->subject));
++      }
++#endif
++
+ #ifndef OPENSSL_NO_SHA
+ /*
+  * Compare two certificates: they must be identical for this to work. NB:
+diff --git a/doc/apps/x509.pod b/doc/apps/x509.pod
+index eba7067..3d18a68 100644
+--- a/doc/apps/x509.pod
++++ b/doc/apps/x509.pod
+@@ -165,6 +165,16 @@ outputs the OCSP hash values for the subject name and public key.
+ synonym for "-subject_hash" for backward compatibility reasons.
++=item B<-subject_hash_old>
++
++outputs the "hash" of the certificate subject name using the older algorithm
++as used by OpenSSL versions before 1.0.0.
++
++=item B<-issuer_hash_old>
++
++outputs the "hash" of the certificate issuer name using the older algorithm
++as used by OpenSSL versions before 1.0.0.
++
+ =item B<-subject>
+ outputs the subject name.
+@@ -847,4 +857,10 @@ L<gendsa(1)|gendsa(1)>, L<verify(1)|verify(1)>
+ Before OpenSSL 0.9.8, the default digest for RSA keys was MD5.
++The hash algorithm used in the B<-subject_hash> and B<-issuer_hash> options
++before OpenSSL 1.0.0 was based on the deprecated MD5 algorithm and the encoding
++of the distinguished name. In OpenSSL 1.0.0 and later it is based on a
++canonical version of the DN using SHA1. This means that any directories using
++the old form must have their links rebuilt using B<c_rehash> or similar. 
++
+ =cut
+-- 
+1.9.1
+
diff --git a/recipes/openssl/openssl-0.9.8zg/c_rehash-compat.patch b/recipes/openssl/openssl-0.9.8zg/c_rehash-compat.patch
new file mode 100644 (file)
index 0000000..9f23556
--- /dev/null
@@ -0,0 +1,34 @@
+diff --git a/tools/c_rehash.in b/tools/c_rehash.in
+index da74501..97f6e2b 100644
+--- a/tools/c_rehash.in
++++ b/tools/c_rehash.in
+@@ -71,6 +71,7 @@ sub hash_dir {
+                       }
+               }
+               link_hash_cert($fname) if($cert);
++              link_hash_cert_old($fname) if($cert);
+               link_hash_crl($fname) if($crl);
+       }
+ }
+@@ -104,8 +105,9 @@ sub check_file {
+ sub link_hash_cert {
+               my $fname = $_[0];
++              my $hashopt = $_[1] || '-subject_hash';
+               $fname =~ s/'/'\\''/g;
+-              my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname'`;
++              my ($hash, $fprint) = `"$openssl" x509 $hashopt -fingerprint -noout -in "$fname"`;
+               chomp $hash;
+               chomp $fprint;
+               $fprint =~ s/^.*=//;
+@@ -131,6 +133,10 @@ sub link_hash_cert {
+               $hashlist{$hash} = $fprint;
+ }
++sub link_hash_cert_old {
++              link_hash_cert($_[0], '-subject_hash_old');
++}
++
+ # Same as above except for a CRL. CRL links are of the form <hash>.r<n>
+ sub link_hash_crl {
index d9d6b70..3bf206d 100644 (file)
@@ -1,10 +1,10 @@
 Upstream-Status: Backport [debian]
 
-Index: openssl-0.9.8k/tools/c_rehash.in
-===================================================================
---- openssl-0.9.8k.orig/tools/c_rehash.in      2002-10-11 22:31:27.000000000 +0200
-+++ openssl-0.9.8k/tools/c_rehash.in   2009-07-19 11:36:26.000000000 +0200
-@@ -59,12 +59,15 @@
+diff --git a/tools/c_rehash.in b/tools/c_rehash.in
+index 8b6d3f5..da74501 100644
+--- a/tools/c_rehash.in
++++ b/tools/c_rehash.in
+@@ -60,12 +60,15 @@ sub hash_dir {
                }
        }
        closedir DIR;
@@ -23,12 +23,12 @@ Index: openssl-0.9.8k/tools/c_rehash.in
                }
                link_hash_cert($fname) if($cert);
                link_hash_crl($fname) if($crl);
-@@ -102,6 +105,9 @@
+@@ -134,6 +137,9 @@ sub link_hash_crl {
                my $fname = $_[0];
                $fname =~ s/'/'\\''/g;
-               my ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname'`;
+               my ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname'`;
 +              if(!$hash || !fprint) {
-+                      ($hash, $fprint) = `"$openssl" x509 -hash -fingerprint -noout -in '$fname' -inform der`;
++                      ($hash, $fprint) = `"$openssl" crl -hash -fingerprint -noout -in '$fname' -inform der`;
 +              }
                chomp $hash;
                chomp $fprint;
index 53d25c2..9773042 100644 (file)
@@ -1,6 +1,6 @@
 require openssl.inc
 
-PR = "r0"
+PR = "r1"
 SRC_URI += "file://debian/ca.patch;patch=1 \
             file://debian/config-hurd.patch;apply=no \
             file://debian/debian-targets.patch;patch=1 \
@@ -25,6 +25,13 @@ SRC_URI += "file://configure-targets.patch;patch=1 \
             file://shared-libs.patch;patch=1 \
             file://parallel-make-fix.patch;patch=1"
 
+# openssl x509 -subject_hash_old support (and -subject_hash change)
+SRC_URI += "file://0001-Store-canonical-encodings-of-Name-structures.patch;patch=1 \
+            file://0002-canonical-related-backports-from-1.0.0s.patch;patch=1 \
+            file://0003-Update-certificate-hash-line-format-to-handle-canoni.patch;patch=1 \
+            file://0004-PR-2136-Submitted-by-Willy-Weisz-weisz-vcpc.univie.a.patch;patch=1 \
+            file://c_rehash-compat.patch;patch=1"
+
 SRC_URI[md5sum] = "0a912b6623ac95a8627ea2bd0e0abf1b"
 SRC_URI[sha256sum] = "06500060639930e471050474f537fcd28ec934af92ee282d78b52460fbe8f580"