diff options
author | Rob Austein <sra@hactrn.net> | 2008-06-17 18:40:40 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2008-06-17 18:40:40 +0000 |
commit | 77afd8cc8a7a0ac3c4733a62507845086524aab8 (patch) | |
tree | 0e808b989ff9b5aa99e3813900250e0749564e6d /utils | |
parent | 6911392ec9d69a7ef5c2ba8207285bf3a2bc26a3 (diff) |
Utility to dump a manifest. This is really a test to see whether I
got the ASN.1 template junk right, but may be useful on its own.
svn path=/utils/Makefile; revision=1895
Diffstat (limited to 'utils')
-rw-r--r-- | utils/Makefile | 2 | ||||
-rw-r--r-- | utils/manifest/Makefile | 24 | ||||
-rw-r--r-- | utils/manifest/manifest.c | 173 |
3 files changed, 198 insertions, 1 deletions
diff --git a/utils/Makefile b/utils/Makefile index e6f7710c..097d2ba4 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -1,6 +1,6 @@ # $Id$ -SUBDIRS = uri +SUBDIRS = uri manifest all clean test: @for i in ${SUBDIRS}; do echo "Making $@ in $$i"; (cd $$i && ${MAKE} $@); done diff --git a/utils/manifest/Makefile b/utils/manifest/Makefile new file mode 100644 index 00000000..1b07a9c2 --- /dev/null +++ b/utils/manifest/Makefile @@ -0,0 +1,24 @@ +# $Id$ + +OPENSSL_DIR = ../../openssl/openssl + +CFLAGS = -g -I${OPENSSL_DIR}/include + +# -H -Wl,-t + +BIN = manifest +OBJ = manifest.o +LIB = ${OPENSSL_DIR}/libcrypto.a + +all: ${BIN} + +clean: + rm -f ${BIN} ${OBJ} + +${BIN}: ${OBJ} ${LIB} Makefile + ${CC} -g -o $@ ${OBJ} ${LIB} + +MANIFEST_DIR = ../../rpkid/testbed.dir/publication + +test: all + if test -d ${MANIFEST_DIR}; then find ${MANIFEST_DIR} -type f -name '*.mnf' -print -exec ./manifest {} \; ; else :; fi diff --git a/utils/manifest/manifest.c b/utils/manifest/manifest.c new file mode 100644 index 00000000..3133dacd --- /dev/null +++ b/utils/manifest/manifest.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008 American Registry for Internet Numbers ("ARIN") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id$ */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> + +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/safestack.h> +#include <openssl/conf.h> +#include <openssl/rand.h> +#include <openssl/asn1.h> +#include <openssl/asn1t.h> +#include <openssl/cms.h> + +/* + * ASN.1 templates for signed manifests. Not sure that ASN1_EXP_OPT() + * is the right macro for "version", but it's what the examples for + * this construction use. Probably doesn't matter since this program + * only decodes manifests, never encodes them. + */ + +typedef struct FileAndHash_st { + ASN1_IA5STRING *file; + ASN1_BIT_STRING *hash; +} FileAndHash; + +ASN1_SEQUENCE(FileAndHash) = { + ASN1_SIMPLE(FileAndHash, file, ASN1_IA5STRING), + ASN1_SIMPLE(FileAndHash, hash, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(FileAndHash) + +DECLARE_STACK_OF(FileAndHash) +DECLARE_ASN1_FUNCTIONS(FileAndHash) + +#define sk_FileAndHash_num(st) SKM_sk_num(FileAndHash, (st)) +#define sk_FileAndHash_value(st, i) SKM_sk_value(FileAndHash, (st), (i)) + +typedef struct Manifest_st { + ASN1_INTEGER *version, *manifestNumber; + ASN1_GENERALIZEDTIME *thisUpdate, *nextUpdate; + ASN1_OBJECT *fileHashAlg; + STACK_OF(FileAndHash) *fileList; +} Manifest; + +ASN1_SEQUENCE(Manifest) = { + ASN1_EXP_OPT(Manifest, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(Manifest, manifestNumber, ASN1_INTEGER), + ASN1_SIMPLE(Manifest, thisUpdate, ASN1_GENERALIZEDTIME), + ASN1_SIMPLE(Manifest, nextUpdate, ASN1_GENERALIZEDTIME), + ASN1_SIMPLE(Manifest, fileHashAlg, ASN1_OBJECT), + ASN1_SEQUENCE_OF(Manifest, fileList, FileAndHash) +} ASN1_SEQUENCE_END(Manifest) + +/* + * Read certificate in DER format. + */ +static X509 *read_cert(const char *filename) +{ + X509 *x = NULL; + BIO *b; + + if ((b = BIO_new_file(filename, "r")) != NULL) + x = d2i_X509_bio(b, NULL); + + BIO_free(b); + return x; +} + +/* + * Read CRL in DER format. + */ +static X509_CRL *read_crl(const char *filename) +{ + X509_CRL *crl = NULL; + BIO *b; + + if ((b = BIO_new_file(filename, "r")) != NULL) + crl = d2i_X509_CRL_bio(b, NULL); + + BIO_free(b); + return crl; +} + +/* + * Read manifest (CMS object) in DER format. + */ +static Manifest *read_manifest(const char *filename) +{ + CMS_ContentInfo *cms = NULL; + Manifest *m = NULL; + char buf[512]; + BIO *b; + int i, j; + + if ((b = BIO_new_file(filename, "r")) == NULL || + (cms = d2i_CMS_bio(b, NULL)) == NULL) + goto done; + BIO_free(b); + +#if 0 + if ((b = BIO_new(BIO_s_fd())) == NULL) + goto done; + BIO_set_fd(b, 1, BIO_NOCLOSE); + CMS_ContentInfo_print_ctx(b, cms, 0, NULL); + BIO_free(b); +#endif + + if ((b = BIO_new(BIO_s_mem())) == NULL || + CMS_verify(cms, NULL, NULL, NULL, b, CMS_NOCRL | CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY | CMS_NO_CONTENT_VERIFY) <= 0 || + (m = ASN1_item_d2i_bio(ASN1_ITEM_rptr(Manifest), b, NULL)) == NULL) + goto done; + + if (m->version) + printf("version: %ld\n", ASN1_INTEGER_get(m->version)); + else + printf("version: 0 [defaulted]\n"); + printf("manifestNumber: %ld\n", ASN1_INTEGER_get(m->manifestNumber)); + printf("thisUpdate: %s\n", m->thisUpdate->data); + printf("nextUpdate: %s\n", m->nextUpdate->data); + OBJ_obj2txt(buf, sizeof(buf), m->fileHashAlg, 0); + printf("fileHashAlg: %s\n", buf); + + for (i = 0; i < sk_FileAndHash_num(m->fileList); i++) { + FileAndHash *fah = sk_FileAndHash_value(m->fileList, i); + printf(" file[%2d]: %s\n", i, fah->file->data); + printf(" hash[%2d]: ", i); + for (j = 0; j < fah->hash->length; j++) + printf("%02x%s", fah->hash->data[j], j == fah->hash->length - 1 ? "\n" : ":"); + } + + done: + if (ERR_peek_error()) + ERR_print_errors_fp(stderr); + BIO_free(b); + CMS_ContentInfo_free(cms); + return m; +} + +/* + * Main program. + */ +int main (int argc, char *argv[]) +{ + Manifest *m; + + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + + m = read_manifest(argv[1]); + return m == NULL; +} |