summaryrefslogtreecommitdiffstats
path: root/main/openssl/0007-reimplement-c_rehash-in-C.patch
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2015-02-05 09:46:51 +0200
committerTimo Teräs <timo.teras@iki.fi>2015-02-23 09:31:04 +0200
commit702892b19b022a42183170314d5ba9f2774baf7c (patch)
tree795a73d491330bcae3c44ee7bab5fab40b88e11b /main/openssl/0007-reimplement-c_rehash-in-C.patch
parentde31a22f0f21b10ef4f8f4d5fc8597a8b2aff497 (diff)
main/openssl: upgrade to 1.0.2 and rebase all patches
Diffstat (limited to 'main/openssl/0007-reimplement-c_rehash-in-C.patch')
-rw-r--r--main/openssl/0007-reimplement-c_rehash-in-C.patch447
1 files changed, 447 insertions, 0 deletions
diff --git a/main/openssl/0007-reimplement-c_rehash-in-C.patch b/main/openssl/0007-reimplement-c_rehash-in-C.patch
new file mode 100644
index 00000000000..eee75d14f5f
--- /dev/null
+++ b/main/openssl/0007-reimplement-c_rehash-in-C.patch
@@ -0,0 +1,447 @@
+From f9044ad2a216f984481645671ccc30a043849fb1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Thu, 5 Feb 2015 09:11:27 +0200
+Subject: [PATCH] reimplement c_rehash in C
+
+---
+ apps/Makefile | 4 +-
+ apps/c_rehash.c | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ tools/Makefile | 3 +-
+ 3 files changed, 386 insertions(+), 4 deletions(-)
+ create mode 100644 apps/c_rehash.c
+
+diff --git a/apps/Makefile b/apps/Makefile
+index 72657ea..3aa03e0 100644
+--- a/apps/Makefile
++++ b/apps/Makefile
+@@ -36,7 +36,7 @@ SCRIPTS=CA.sh CA.pl tsget
+ EXE= $(PROGRAM)$(EXE_EXT)
+
+ E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
+- ca crl rsa rsautl dsa dsaparam ec ecparam \
++ ca crl c_rehash rsa rsautl dsa dsaparam ec ecparam \
+ x509 genrsa gendsa genpkey s_server s_client speed \
+ s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
+ pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp
+@@ -51,7 +51,7 @@ RAND_OBJ=app_rand.o
+ RAND_SRC=app_rand.c
+
+ E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
+- ca.o pkcs7.o crl2p7.o crl.o \
++ ca.o pkcs7.o crl2p7.o crl.o c_rehash.o \
+ rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
+ x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
+ s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
+diff --git a/apps/c_rehash.c b/apps/c_rehash.c
+new file mode 100644
+index 0000000..e8d0b86
+--- /dev/null
++++ b/apps/c_rehash.c
+@@ -0,0 +1,383 @@
++/* c_rehash.c - Create hash symlinks for certificates
++ * C implementation based on the original Perl and shell versions
++ *
++ * Copyright (c) 2013-2014 Timo Teräs <timo.teras@iki.fi>
++ * All rights reserved.
++ *
++ * This software is licensed under the MIT License.
++ * Full license available at: http://opensource.org/licenses/MIT
++ */
++
++#include <stdio.h>
++#include <limits.h>
++#include <string.h>
++#include <unistd.h>
++#include <dirent.h>
++#include <sys/stat.h>
++
++#include <openssl/evp.h>
++#include <openssl/pem.h>
++#include <openssl/x509.h>
++
++#include "apps.h"
++
++#undef PROG
++#define PROG c_rehash_main
++
++
++#define MAX_COLLISIONS 256
++#define countof(x) (sizeof(x) / sizeof(x[0]))
++
++#if 0
++#define DEBUG(args...) fprintf(stderr, args)
++#else
++#define DEBUG(args...)
++#endif
++
++struct entry_info {
++ struct entry_info *next;
++ char *filename;
++ unsigned short old_id;
++ unsigned char need_symlink;
++ unsigned char digest[EVP_MAX_MD_SIZE];
++};
++
++struct bucket_info {
++ struct bucket_info *next;
++ struct entry_info *first_entry, *last_entry;
++ unsigned int hash;
++ unsigned short type;
++ unsigned short num_needed;
++};
++
++enum Type {
++ TYPE_CERT = 0,
++ TYPE_CRL
++};
++
++static const char *symlink_extensions[] = { "", "r" };
++static const char *file_extensions[] = { "pem", "crt", "cer", "crl" };
++
++static int evpmdsize;
++static const EVP_MD *evpmd;
++
++static int do_hash_new = 1;
++static int do_hash_old = 0;
++static int do_remove_links = 1;
++static int do_verbose = 0;
++
++static struct bucket_info *hash_table[257];
++
++static void bit_set(unsigned char *set, unsigned bit)
++{
++ set[bit / 8] |= 1 << (bit % 8);
++}
++
++static int bit_isset(unsigned char *set, unsigned bit)
++{
++ return set[bit / 8] & (1 << (bit % 8));
++}
++
++static void add_entry(
++ int type, unsigned int hash,
++ const char *filename, const unsigned char *digest,
++ int need_symlink, unsigned short old_id)
++{
++ struct bucket_info *bi;
++ struct entry_info *ei, *found = NULL;
++ unsigned int ndx = (type + hash) % countof(hash_table);
++
++ for (bi = hash_table[ndx]; bi; bi = bi->next)
++ if (bi->type == type && bi->hash == hash)
++ break;
++ if (!bi) {
++ bi = calloc(1, sizeof(*bi));
++ if (!bi) return;
++ bi->next = hash_table[ndx];
++ bi->type = type;
++ bi->hash = hash;
++ hash_table[ndx] = bi;
++ }
++
++ for (ei = bi->first_entry; ei; ei = ei->next) {
++ if (digest && memcmp(digest, ei->digest, evpmdsize) == 0) {
++ BIO_printf(bio_err,
++ "WARNING: Skipping duplicate certificate in file %s\n",
++ filename);
++ return;
++ }
++ if (!strcmp(filename, ei->filename)) {
++ found = ei;
++ if (!digest) break;
++ }
++ }
++ ei = found;
++ if (!ei) {
++ if (bi->num_needed >= MAX_COLLISIONS) return;
++ ei = calloc(1, sizeof(*ei));
++ if (!ei) return;
++
++ ei->old_id = ~0;
++ ei->filename = strdup(filename);
++ if (bi->last_entry) bi->last_entry->next = ei;
++ if (!bi->first_entry) bi->first_entry = ei;
++ bi->last_entry = ei;
++ }
++
++ if (old_id < ei->old_id) ei->old_id = old_id;
++ if (need_symlink && !ei->need_symlink) {
++ ei->need_symlink = 1;
++ bi->num_needed++;
++ memcpy(ei->digest, digest, evpmdsize);
++ }
++}
++
++static int handle_symlink(const char *filename, const char *fullpath)
++{
++ static char xdigit[] = {
++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
++ -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
++ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
++ -1,10,11,12,13,14,15
++ };
++ char linktarget[NAME_MAX], *endptr;
++ unsigned int hash = 0;
++ unsigned char ch;
++ int i, type, id;
++ ssize_t n;
++
++ for (i = 0; i < 8; i++) {
++ ch = filename[i] - '0';
++ if (ch >= countof(xdigit) || xdigit[ch] < 0)
++ return -1;
++ hash <<= 4;
++ hash += xdigit[ch];
++ }
++ if (filename[i++] != '.') return -1;
++ for (type = countof(symlink_extensions) - 1; type > 0; type--)
++ if (strcasecmp(symlink_extensions[type], &filename[i]) == 0)
++ break;
++ i += strlen(symlink_extensions[type]);
++
++ id = strtoul(&filename[i], &endptr, 10);
++ if (*endptr != 0) return -1;
++
++ n = readlink(fullpath, linktarget, sizeof(linktarget));
++ if (n >= sizeof(linktarget) || n < 0) return -1;
++ linktarget[n] = 0;
++
++ DEBUG("Found existing symlink %s for %08x (%d), certname %s\n",
++ filename, hash, type, linktarget);
++ add_entry(type, hash, linktarget, NULL, 0, id);
++ return 0;
++}
++
++static int handle_certificate(const char *filename, const char *fullpath)
++{
++ STACK_OF(X509_INFO) *inf;
++ X509_INFO *x;
++ BIO *b;
++ const char *ext;
++ unsigned char digest[EVP_MAX_MD_SIZE];
++ X509_NAME *name = NULL;
++ int i, type, ret = -1;
++
++ ext = strrchr(filename, '.');
++ if (ext == NULL) return 0;
++ for (i = 0; i < countof(file_extensions); i++) {
++ if (strcasecmp(file_extensions[i], ext+1) == 0)
++ break;
++ }
++ if (i >= countof(file_extensions)) return -1;
++
++ b = BIO_new_file(fullpath, "r");
++ if (!b) return -1;
++ inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
++ BIO_free(b);
++ if (!inf) return -1;
++
++ if (sk_X509_INFO_num(inf) == 1) {
++ x = sk_X509_INFO_value(inf, 0);
++ if (x->x509) {
++ type = TYPE_CERT;
++ name = X509_get_subject_name(x->x509);
++ X509_digest(x->x509, evpmd, digest, NULL);
++ } else if (x->crl) {
++ type = TYPE_CRL;
++ name = X509_CRL_get_issuer(x->crl);
++ X509_CRL_digest(x->crl, evpmd, digest, NULL);
++ }
++ if (name && do_hash_new)
++ add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0);
++ if (name && do_hash_old)
++ add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0);
++ } else {
++ BIO_printf(bio_err,
++ "WARNING: %s does not contain exactly one certificate or CRL: skipping\n",
++ filename);
++ }
++
++ sk_X509_INFO_pop_free(inf, X509_INFO_free);
++
++ return ret;
++}
++
++static int hash_dir(const char *dirname)
++{
++ struct bucket_info *bi, *nextbi;
++ struct entry_info *ei, *nextei;
++ struct dirent *de;
++ struct stat st;
++ unsigned char idmask[MAX_COLLISIONS / 8];
++ int i, n, nextid, buflen, ret = -1;
++ const char *pathsep;
++ char *buf;
++ DIR *d;
++
++ if (access(dirname, R_OK|W_OK|X_OK) != 0) {
++ BIO_printf(bio_err,
++ "ERROR: Access denied '%s'\n",
++ dirname);
++ return -1;
++ }
++
++ buflen = strlen(dirname);
++ pathsep = (buflen && dirname[buflen-1] == '/') ? "" : "/";
++ buflen += NAME_MAX + 2;
++ buf = malloc(buflen);
++ if (buf == NULL)
++ goto err;
++
++ if (do_verbose) printf("Doing %s\n", dirname);
++ d = opendir(dirname);
++ if (!d) goto err;
++
++ while ((de = readdir(d)) != NULL) {
++ if (snprintf(buf, buflen, "%s%s%s", dirname, pathsep, de->d_name) >= buflen)
++ continue;
++ if (lstat(buf, &st) < 0)
++ continue;
++ if (S_ISLNK(st.st_mode) && handle_symlink(de->d_name, buf) == 0)
++ continue;
++ handle_certificate(de->d_name, buf);
++ }
++ closedir(d);
++
++ for (i = 0; i < countof(hash_table); i++) {
++ for (bi = hash_table[i]; bi; bi = nextbi) {
++ nextbi = bi->next;
++ DEBUG("Type %d, hash %08x, num entries %d:\n", bi->type, bi->hash, bi->num_needed);
++
++ nextid = 0;
++ memset(idmask, 0, (bi->num_needed+7)/8);
++ for (ei = bi->first_entry; ei; ei = ei->next)
++ if (ei->old_id < bi->num_needed)
++ bit_set(idmask, ei->old_id);
++
++ for (ei = bi->first_entry; ei; ei = nextei) {
++ nextei = ei->next;
++ DEBUG("\t(old_id %d, need_symlink %d) Cert %s\n",
++ ei->old_id, ei->need_symlink,
++ ei->filename);
++
++ if (ei->old_id < bi->num_needed) {
++ /* Link exists, and is used as-is */
++ snprintf(buf, buflen, "%08x.%s%d", bi->hash, symlink_extensions[bi->type], ei->old_id);
++ if (do_verbose) printf("link %s -> %s\n", ei->filename, buf);
++ } else if (ei->need_symlink) {
++ /* New link needed (it may replace something) */
++ while (bit_isset(idmask, nextid))
++ nextid++;
++
++ snprintf(buf, buflen, "%s%s%n%08x.%s%d",
++ dirname, pathsep, &n, bi->hash,
++ symlink_extensions[bi->type],
++ nextid);
++ if (do_verbose) printf("link %s -> %s\n", ei->filename, &buf[n]);
++ unlink(buf);
++ symlink(ei->filename, buf);
++ } else if (do_remove_links) {
++ /* Link to be deleted */
++ snprintf(buf, buflen, "%s%s%n%08x.%s%d",
++ dirname, pathsep, &n, bi->hash,
++ symlink_extensions[bi->type],
++ ei->old_id);
++ if (do_verbose) printf("unlink %s\n", &buf[n]);
++ unlink(buf);
++ }
++ free(ei->filename);
++ free(ei);
++ }
++ free(bi);
++ }
++ hash_table[i] = NULL;
++ }
++
++ ret = 0;
++err:
++ free(buf);
++ return ret;
++}
++
++static void c_rehash_usage(void)
++{
++ printf("\
++usage: c_rehash <args> <dirs>\n\
++\n\
++-compat - create new- and old-style hashed links\n\
++-old - use old-style hashing for generating links\n\
++-h - display this help\n\
++-n - do not remove existing links\n\
++-v - be more verbose\n\
++\n");
++}
++
++int MAIN(int argc, char **argv)
++{
++ const char *env, *opt;
++ int i, numargs, r = 0;
++
++ evpmd = EVP_sha1();
++ evpmdsize = EVP_MD_size(evpmd);
++ if (bio_err == NULL)
++ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
++
++ numargs = argc;
++ for (i = 1; i < argc; i++) {
++ if (argv[i][0] != '-') continue;
++ if (strcmp(argv[i], "--") == 0) { argv[i] = 0; numargs--; break; }
++ opt = &argv[i][1];
++ if (strcmp(opt, "compat") == 0) {
++ do_hash_new = do_hash_old = 1;
++ } else if (strcmp(opt, "old") == 0) {
++ do_hash_new = 0;
++ do_hash_old = 1;
++ } else if (strcmp(opt, "n") == 0) {
++ do_remove_links = 0;
++ } else if (strcmp(opt, "v") == 0) {
++ do_verbose++;
++ } else {
++ if (strcmp(opt, "h") != 0)
++ BIO_printf(bio_err,"unknown option %s\n", argv[i]);
++ c_rehash_usage();
++ return 1;
++ }
++ argv[i] = 0;
++ numargs--;
++ }
++
++ if (numargs > 1) {
++ for (i = 1; i < argc; i++)
++ if (argv[i]) r |= hash_dir(argv[i]);
++ } else if ((env = getenv("SSL_CERT_DIR")) != NULL) {
++ char *e, *m;
++ m = strdup(env);
++ for (e = strtok(m, ":"); e != NULL; e = strtok(NULL, ":"))
++ r |= hash_dir(e);
++ free(m);
++ } else {
++ r |= hash_dir("/etc/ssl/certs");
++ }
++
++ return r ? 2 : 0;
++}
+diff --git a/tools/Makefile b/tools/Makefile
+index bb6fb71..51190fc 100644
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -13,7 +13,7 @@ CFLAGS= $(INCLUDES) $(CFLAG)
+
+ GENERAL=Makefile
+ TEST=
+-APPS= c_rehash
++APPS=
+ MISC_APPS= c_hash c_info c_issuer c_name
+
+ all:
+@@ -49,7 +49,6 @@ depend:
+ dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+- rm -f c_rehash
+
+ clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+--
+2.2.2
+