summaryrefslogtreecommitdiffstats
path: root/tdeio/kssl/kssl/cert_extract.c
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/kssl/kssl/cert_extract.c')
-rw-r--r--tdeio/kssl/kssl/cert_extract.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/tdeio/kssl/kssl/cert_extract.c b/tdeio/kssl/kssl/cert_extract.c
new file mode 100644
index 000000000..095f810f4
--- /dev/null
+++ b/tdeio/kssl/kssl/cert_extract.c
@@ -0,0 +1,183 @@
+//krazy:excludeall=license (program, not a library)
+/*
+** cert_extract.c -- Extract CA Certs out of Netscape certN.db files
+**
+** Copyright Ariel Glenn <ariel@columbia.edu>
+** Copyright 1998 Ralf S. Engelschall <rse@engelschall.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+**
+**
+** Originally written and released under the GPL by
+** Ariel Glenn from the AcIS R&D group at Columbia
+** as the two sources findoffset.c and dblist.c. See under
+** http://www.columbia.edu/~ariel/good-certs/ for more details.
+**
+** Merged into one single program in August 1998
+** by Ralf S. Engelschall for use in the mod_ssl project.
+** See under http://www.engelschall.com/sw/mod_ssl/ for more details.
+**
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <db1/db.h>
+
+#include "openssl/asn1.h"
+#include "openssl/x509.h"
+
+int findoffset(char *dbname);
+
+int findoffset(char *dbname)
+{
+ DB *db;
+ DBT dkey, dvalue;
+ int result;
+ int offset = 0;
+ char *p;
+ int ptag = 0, pclass, plen;
+ X509 *mycert;
+
+ if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL) {
+ fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
+ exit(1);
+ }
+ while ((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0) {
+ if ((dvalue.size) > 520) {
+ while (offset < dvalue.size) {
+ p = (char *)dvalue.data + offset - 1;
+ ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
+ if (ptag == V_ASN1_SEQUENCE) { /* ok, it might be a cert then. */
+ /* include length of object header junk */
+ plen += p - ((char *) dvalue.data + offset - 1);
+ mycert = NULL;
+ p = (char *) dvalue.data + offset - 1;
+ d2i_X509(&mycert, (unsigned char **) &p, plen);
+ if (mycert == NULL) { /* must be garbage after all */
+ offset++;
+ continue;
+ }
+ break;
+ }
+ else
+ offset++;
+ }
+ if (offset > 0)
+ break; /* found it, let's quit */
+ }
+ }
+ db->close(db);
+ return (offset);
+}
+
+int main(int argc, char **argv)
+{
+ char *dbname;
+ DB *db;
+ int j;
+ int offset;
+ DBT dkey, dvalue;
+ int result;
+ char oname[40];
+ int fout;
+ int find;
+ char *p;
+ int ptag = 0, pclass, plen;
+ X509 *mycert;
+ char *shortname;
+ char byte1, byte2;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s /path/to/netscape/cert.db\n", argv[0]);
+ exit(1);
+ }
+
+ dbname = argv[1];
+ offset = findoffset(dbname);
+ if (offset == 0) {
+ fprintf(stderr, "Could not determine cert offset in DB file '%s'\n", dbname);
+ exit(1);
+ }
+ else {
+ fprintf(stderr, "Ok: certificates are at offset %d\n", offset);
+ }
+
+ if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL) {
+ fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
+ exit(1);
+ }
+ if ((find = open("cert.index", O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1) {
+ fprintf(stderr, "Failed to open Index file '%s': %s\n", "cert-index", strerror(errno));
+ exit(1);
+ }
+ j = 0;
+ byte1 = -1;
+ byte2 = -1;
+ while ((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0) {
+ if (dvalue.size > offset && ((dvalue.size) - offset) > 500) {
+ p = (char *)dvalue.data + offset - 1;
+ if (byte1 != -1 && byte2 != -1)
+ if (byte1 != p[0] || byte2 != p[1])
+ continue;
+ ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
+ if (ptag == V_ASN1_SEQUENCE) { /* ok, it might be a cert then. */
+ if (byte1 == -1 && byte2 == -1) {
+ byte1 = p[0];
+ byte2 = p[1];
+ }
+ /* include length of object header junk */
+ plen += p - ((char *) dvalue.data + offset - 1);
+ mycert = NULL;
+ p = (char *) dvalue.data + offset - 1;
+ d2i_X509(&mycert, (unsigned char **) &p, plen);
+ if (mycert == NULL) { /* must be garbage after all */
+ continue;
+ }
+ j++;
+ sprintf(oname, "cert.%02d.der", j);
+ if ((fout = open(oname, O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1) {
+ fprintf(stderr, "could not open %s\n", oname);
+ continue;
+ }
+ write(fout, (char *) dvalue.data + offset - 1, plen);
+ close(fout);
+ write(find, oname, strlen(oname));
+ write(find, ": ", 2);
+ shortname = (char *) dvalue.data + offset - 1 + plen;
+ write(find, shortname, dvalue.size - plen - offset);
+ write(find, "\n", 1);
+ fprintf(stderr, "Extracted: %s (", oname);
+ write(fileno(stderr), shortname, dvalue.size - plen - offset);
+ fprintf(stderr, ")\n");
+ }
+ else {
+ /* fprintf(stderr, "Hmmm... ptag is %d, plen is %d\n", ptag, plen); */
+ }
+ }
+ }
+ close(find);
+ db->close(db);
+
+ return (0);
+}
+