Пример #1
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 {
		fprintf(stderr,
			"WARNING: %s does not contain exactly one certificate or CRL: skipping\n",
			filename);
	}

	sk_X509_INFO_pop_free(inf, X509_INFO_free);

	return ret;
}
Пример #2
0
static LUA_FUNCTION(openssl_crl_digest)
{
  X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl");
  byte buf[EVP_MAX_MD_SIZE];
  unsigned int lbuf = sizeof(buf);
  const EVP_MD *md = lua_isnoneornil(L, 2)
                     ? EVP_get_digestbyname("sha1") : get_digest(L, 2);

  int ret =  X509_CRL_digest(crl, md, buf, &lbuf);
  if (ret == 1)
  {
    lua_pushlstring(L, (const char*)buf, (size_t)lbuf);
    return ret;
  }
  return openssl_pushresult(L, ret);
}
Пример #3
0
static int hash_file(int dirfd, const char *filename)
{
	STACK_OF(X509_INFO) *inf;
	X509_INFO *x;
	BIO *b;
	int i, count = 0;
	unsigned char digest[EVP_MAX_MD_SIZE];

	b = BIO_openat(dirfd, filename);
	if (!b)
		return -1;

	inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
	BIO_free(b);
	if (!inf)
		return -1;

	for(i = 0; i < sk_X509_INFO_num(inf); i++) {
		x = sk_X509_INFO_value(inf, i);
		if (x->x509) {
			X509_digest(x->x509, evpmd, digest, NULL);
			link_file(dirfd, filename, TYPE_CERT,
				  X509_subject_name_hash(x->x509), digest);
			count++;
		}
		if (x->crl) {
			X509_CRL_digest(x->crl, evpmd, digest, NULL);
			link_file(dirfd, filename, TYPE_CRL,
				  X509_NAME_hash(X509_CRL_get_issuer(x->crl)),
				  digest);
			count++;
		}
	}
	sk_X509_INFO_pop_free(inf, X509_INFO_free);

	if (count == 0) {
		fprintf(stderr,
			"WARNING: %s does not contain a certificate or CRL: skipping\n",
			filename);
	}

	return count;
}
Пример #4
0
static LUA_FUNCTION(openssl_crl_parse)
{
  X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl");
  int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2);
  int n, i;

  lua_newtable(L);
  AUXILIAR_SET(L, -1, "version", X509_CRL_get_version(crl), integer);

  /* hash as used in CA directories to lookup cert by subject name */
  {
    char buf[32];
    snprintf(buf, sizeof(buf), "%08lx", X509_NAME_hash(X509_CRL_get_issuer(crl)));
    AUXILIAR_SET(L, -1, "hash", buf, string);
  }

  {
    const EVP_MD *digest = EVP_get_digestbyname("sha1");
    unsigned char md[EVP_MAX_MD_SIZE];
    int n = sizeof(md);

    if (X509_CRL_digest(crl, digest, md, (unsigned int*)&n))
    {
      lua_newtable(L);
      AUXILIAR_SET(L, -1, "alg", OBJ_nid2sn(EVP_MD_type(digest)), string);
      AUXILIAR_SETLSTR(L, -1, "hash", (const char*)md, n);

      lua_setfield(L, -2, "fingerprint");
    }
  }

  openssl_push_xname_asobject(L, X509_CRL_get_issuer(crl));
  lua_setfield(L, -2, "issuer");

  PUSH_ASN1_TIME(L,X509_CRL_get_lastUpdate(crl));
  lua_setfield(L, -2, "lastUpdate");
  PUSH_ASN1_TIME(L,X509_CRL_get_nextUpdate(crl));
  lua_setfield(L, -2, "nextUpdate");

  openssl_push_x509_algor(L, crl->crl->sig_alg);
  lua_setfield(L, -2, "sig_alg");
  
  PUSH_ASN1_INTEGER(L, X509_CRL_get_ext_d2i(crl, NID_crl_number, NULL, NULL));
  lua_setfield(L, -2, "crl_number");

  PUSH_OBJECT(sk_X509_EXTENSION_dup(crl->crl->extensions),"openssl.stack_of_x509_extension");
  lua_setfield(L, -2, "extensions");

  n = sk_X509_REVOKED_num(crl->crl->revoked);
  lua_newtable(L);
  for (i = 0; i < n; i++)
  {
    X509_REVOKED *revoked = sk_X509_REVOKED_value(crl->crl->revoked, i);
    lua_newtable(L);

#if OPENSSL_VERSION_NUMBER > 0x10000000L
    AUXILIAR_SET(L, -1, "CRLReason", reason_flags[revoked->reason].lname, string);
#else
    {
      int crit = 0;
      void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL);

      AUXILIAR_SET(L, -1, "CRLReason", reason_flags[ASN1_ENUMERATED_get(reason)].lname, string);
      ASN1_ENUMERATED_free(reason);
    }
#endif
    PUSH_ASN1_INTEGER(L, revoked->serialNumber);
    lua_setfield(L,-2, "serialNumber");

    PUSH_ASN1_TIME(L, revoked->revocationDate);
    lua_setfield(L,-2, "revocationDate");

    PUSH_OBJECT(sk_X509_EXTENSION_dup(revoked->extensions),"openssl.stack_of_x509_extension");
    lua_setfield(L,-2, "extensions");

    lua_rawseti(L, -2, i + 1);
  }

  lua_setfield(L, -2, "revoked");
  return 1;
}
Пример #5
0
/*
 * The X509_CRL structure needs a bit of customisation. Cache some extensions
 * and hash of the whole CRL.
 */
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                  void *exarg)
{
    X509_CRL *crl = (X509_CRL *)*pval;
    STACK_OF(X509_EXTENSION) *exts;
    X509_EXTENSION *ext;
    int idx;

    switch (operation) {
    case ASN1_OP_NEW_POST:
        crl->idp = NULL;
        crl->akid = NULL;
        crl->flags = 0;
        crl->idp_flags = 0;
        crl->idp_reasons = CRLDP_ALL_REASONS;
        crl->meth = default_crl_method;
        crl->meth_data = NULL;
        crl->issuers = NULL;
        crl->crl_number = NULL;
        crl->base_crl_number = NULL;
        break;

    case ASN1_OP_D2I_POST:
        X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
        crl->idp = X509_CRL_get_ext_d2i(crl,
                                        NID_issuing_distribution_point, NULL,
                                        NULL);
        if (crl->idp)
            setup_idp(crl, crl->idp);

        crl->akid = X509_CRL_get_ext_d2i(crl,
                                         NID_authority_key_identifier, NULL,
                                         NULL);

        crl->crl_number = X509_CRL_get_ext_d2i(crl,
                                               NID_crl_number, NULL, NULL);

        crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
                                                    NID_delta_crl, NULL,
                                                    NULL);
        /* Delta CRLs must have CRL number */
        if (crl->base_crl_number && !crl->crl_number)
            crl->flags |= EXFLAG_INVALID;

        /*
         * See if we have any unhandled critical CRL extensions and indicate
         * this in a flag. We only currently handle IDP so anything else
         * critical sets the flag. This code accesses the X509_CRL structure
         * directly: applications shouldn't do this.
         */

        exts = crl->crl.extensions;

        for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
            int nid;
            ext = sk_X509_EXTENSION_value(exts, idx);
            nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
            if (nid == NID_freshest_crl)
                crl->flags |= EXFLAG_FRESHEST;
            if (X509_EXTENSION_get_critical(ext)) {
                /* We handle IDP and deltas */
                if ((nid == NID_issuing_distribution_point)
                    || (nid == NID_authority_key_identifier)
                    || (nid == NID_delta_crl))
                    break;;
                crl->flags |= EXFLAG_CRITICAL;
                break;
            }
        }

        if (!crl_set_issuers(crl))
            return 0;

        if (crl->meth->crl_init) {
            if (crl->meth->crl_init(crl) == 0)
                return 0;
        }
        break;

    case ASN1_OP_FREE_POST:
        if (crl->meth->crl_free) {
            if (!crl->meth->crl_free(crl))
                return 0;
        }
        AUTHORITY_KEYID_free(crl->akid);
        ISSUING_DIST_POINT_free(crl->idp);
        ASN1_INTEGER_free(crl->crl_number);
        ASN1_INTEGER_free(crl->base_crl_number);
        sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
        break;
    }
    return 1;
}
int MAIN(int argc, char **argv)
{
    X509_CRL *x=NULL;
    char *CAfile = NULL, *CApath = NULL;
    int ret=1,i,num,badops=0;
    BIO *out=NULL;
    int informat,outformat;
    char *infile=NULL,*outfile=NULL;
    int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
    int fingerprint = 0;
    char **pp,buf[256];
    X509_STORE *store = NULL;
    X509_STORE_CTX ctx;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    int do_ver = 0;
    const EVP_MD *md_alg,*digest=EVP_md5();

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err=BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

    if (bio_out == NULL)
        if ((bio_out=BIO_new(BIO_s_file())) != NULL)
        {
            BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
#ifdef VMS
            {
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
                bio_out = BIO_push(tmpbio, bio_out);
            }
#endif
        }

    informat=FORMAT_PEM;
    outformat=FORMAT_PEM;

    argc--;
    argv++;
    num=0;
    while (argc >= 1)
    {
#ifdef undef
        if	(strcmp(*argv,"-p") == 0)
        {
            if (--argc < 1) goto bad;
            if (!args_from_file(++argv,Nargc,Nargv)) {
                goto end;
            }*/
        }
#endif
        if 	(strcmp(*argv,"-inform") == 0)
        {
            if (--argc < 1) goto bad;
            informat=str2fmt(*(++argv));
        }
        else if (strcmp(*argv,"-outform") == 0)
        {
            if (--argc < 1) goto bad;
            outformat=str2fmt(*(++argv));
        }
        else if (strcmp(*argv,"-in") == 0)
        {
            if (--argc < 1) goto bad;
            infile= *(++argv);
        }
        else if (strcmp(*argv,"-out") == 0)
        {
            if (--argc < 1) goto bad;
            outfile= *(++argv);
        }
        else if (strcmp(*argv,"-CApath") == 0)
        {
            if (--argc < 1) goto bad;
            CApath = *(++argv);
            do_ver = 1;
        }
        else if (strcmp(*argv,"-CAfile") == 0)
        {
            if (--argc < 1) goto bad;
            CAfile = *(++argv);
            do_ver = 1;
        }
        else if (strcmp(*argv,"-verify") == 0)
            do_ver = 1;
        else if (strcmp(*argv,"-text") == 0)
            text = 1;
        else if (strcmp(*argv,"-hash") == 0)
            hash= ++num;
        else if (strcmp(*argv,"-issuer") == 0)
            issuer= ++num;
        else if (strcmp(*argv,"-lastupdate") == 0)
            lastupdate= ++num;
        else if (strcmp(*argv,"-nextupdate") == 0)
            nextupdate= ++num;
        else if (strcmp(*argv,"-noout") == 0)
            noout= ++num;
        else if (strcmp(*argv,"-fingerprint") == 0)
            fingerprint= ++num;
        else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
        {
            /* ok */
            digest=md_alg;
        }
        else
        {
            BIO_printf(bio_err,"unknown option %s\n",*argv);
            badops=1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops)
    {
bad:
        for (pp=crl_usage; (*pp != NULL); pp++)
            BIO_printf(bio_err,*pp);
        goto end;
    }

    ERR_load_crypto_strings();
    x=load_crl(infile,informat);
    if (x == NULL) {
        goto end;
    }

    if(do_ver) {
        store = X509_STORE_new();
        lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
        if (lookup == NULL) goto end;
        if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
            X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);

        lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
        if (lookup == NULL) goto end;
        if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
            X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        ERR_clear_error();

        X509_STORE_CTX_init(&ctx, store, NULL, NULL);

        i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
                                      X509_CRL_get_issuer(x), &xobj);
        if(i <= 0) {
            BIO_printf(bio_err,
                       "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get_pubkey(xobj.data.x509);
        X509_OBJECT_free_contents(&xobj);
        if(!pkey) {
            BIO_printf(bio_err,
                       "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        EVP_PKEY_free(pkey);
        if(i < 0) goto end;
        if(i == 0) BIO_printf(bio_err, "verify failure\n");
        else BIO_printf(bio_err, "verify OK\n");
    }

    if (num)
    {
        for (i=1; i<=num; i++)
        {
            if (issuer == i)
            {
                X509_NAME_oneline(X509_CRL_get_issuer(x),
                                  buf,256);
                BIO_printf(bio_out,"issuer= %s\n",buf);
            }

            if (hash == i)
            {
                BIO_printf(bio_out,"%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
            if (lastupdate == i)
            {
                BIO_printf(bio_out,"lastUpdate=");
                ASN1_TIME_print(bio_out,
                                X509_CRL_get_lastUpdate(x));
                BIO_printf(bio_out,"\n");
            }
            if (nextupdate == i)
            {
                BIO_printf(bio_out,"nextUpdate=");
                if (X509_CRL_get_nextUpdate(x))
                    ASN1_TIME_print(bio_out,
                                    X509_CRL_get_nextUpdate(x));
                else
                    BIO_printf(bio_out,"NONE");
                BIO_printf(bio_out,"\n");
            }
            if (fingerprint == i)
            {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x,digest,md,&n))
                {
                    BIO_printf(bio_err,"out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out,"%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j=0; j<(int)n; j++)
                {
                    BIO_printf(bio_out,"%02X%c",md[j],
                               (j+1 == (int)n)
                               ?'\n':':');
                }
            }
        }
    }

    out=BIO_new(BIO_s_file());
    if (out == NULL)
    {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (outfile == NULL)
    {
        BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
#endif
    }
    else
    {
        if (BIO_write_filename(out,outfile) <= 0)
        {
            perror(outfile);
            goto end;
        }
    }

    if (text) X509_CRL_print(out, x);

    if (noout) goto end;

    if 	(outformat == FORMAT_ASN1)
        i=(int)i2d_X509_CRL_bio(out,x);
    else if (outformat == FORMAT_PEM)
        i=PEM_write_bio_X509_CRL(out,x);
    else
    {
        BIO_printf(bio_err,"bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err,"unable to write CRL\n");
        goto end;
    }
    ret=0;
end:
    BIO_free_all(out);
    BIO_free_all(bio_out);
    bio_out=NULL;
    X509_CRL_free(x);
    if(store) {
        X509_STORE_CTX_cleanup(&ctx);
        X509_STORE_free(store);
    }
    EXIT(ret);
}
Пример #7
0
int crl_main(int argc, char **argv)
{
    X509_CRL *x = NULL;
    BIO *out = NULL;
    X509_STORE *store = NULL;
    X509_STORE_CTX *ctx = NULL;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT *xobj = NULL;
    EVP_PKEY *pkey;
    const EVP_MD *digest = EVP_sha1();
    unsigned long nmflag = 0;
    char nmflag_set = 0;
    char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
    const char *CAfile = NULL, *CApath = NULL, *prog;
    OPTION_CHOICE o;
    int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
    int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0;
    int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0;
    int i;
#ifndef OPENSSL_NO_MD5
    int hash_old = 0;
#endif

    prog = opt_init(argc, argv, crl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(crl_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_KEY:
            keyfile = opt_arg();
            break;
        case OPT_GENDELTA:
            crldiff = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            do_ver = 1;
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            do_ver = 1;
            break;
        case OPT_NOCAPATH:
            noCApath =  1;
            break;
        case OPT_NOCAFILE:
            noCAfile =  1;
            break;
        case OPT_HASH_OLD:
#ifndef OPENSSL_NO_MD5
            hash_old = ++num;
#endif
            break;
        case OPT_VERIFY:
            do_ver = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_HASH:
            hash = ++num;
            break;
        case OPT_ISSUER:
            issuer = ++num;
            break;
        case OPT_LASTUPDATE:
            lastupdate = ++num;
            break;
        case OPT_NEXTUPDATE:
            nextupdate = ++num;
            break;
        case OPT_NOOUT:
            noout = ++num;
            break;
        case OPT_FINGERPRINT:
            fingerprint = ++num;
            break;
        case OPT_CRLNUMBER:
            crlnumber = ++num;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
        case OPT_NAMEOPT:
            nmflag_set = 1;
            if (!set_name_ex(&nmflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &digest))
                goto opthelp;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (!nmflag_set)
        nmflag = XN_FLAG_ONELINE;

    x = load_crl(infile, informat);
    if (x == NULL)
        goto end;

    if (do_ver) {
        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
            goto end;
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        if (lookup == NULL)
            goto end;
        ctx = X509_STORE_CTX_new();
        if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
            BIO_printf(bio_err, "Error initialising X509 store\n");
            goto end;
        }

        xobj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509,
                                                 X509_CRL_get_issuer(x));
        if (xobj == NULL) {
            BIO_printf(bio_err, "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
        X509_OBJECT_free(xobj);
        if (!pkey) {
            BIO_printf(bio_err, "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0)
            goto end;
        if (i == 0)
            BIO_printf(bio_err, "verify failure\n");
        else
            BIO_printf(bio_err, "verify OK\n");
    }

    if (crldiff) {
        X509_CRL *newcrl, *delta;
        if (!keyfile) {
            BIO_puts(bio_err, "Missing CRL signing key\n");
            goto end;
        }
        newcrl = load_crl(crldiff, informat);
        if (!newcrl)
            goto end;
        pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key");
        if (!pkey) {
            X509_CRL_free(newcrl);
            goto end;
        }
        delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
        X509_CRL_free(newcrl);
        EVP_PKEY_free(pkey);
        if (delta) {
            X509_CRL_free(x);
            x = delta;
        } else {
            BIO_puts(bio_err, "Error creating delta CRL\n");
            goto end;
        }
    }

    if (badsig) {
        const ASN1_BIT_STRING *sig;

        X509_CRL_get0_signature(x, &sig, NULL);
        corrupt_signature(sig);
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
                           nmflag);
            }
            if (crlnumber == i) {
                ASN1_INTEGER *crlnum;
                crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL);
                BIO_printf(bio_out, "crlNumber=");
                if (crlnum) {
                    i2a_ASN1_INTEGER(bio_out, crlnum);
                    ASN1_INTEGER_free(crlnum);
                } else
                    BIO_puts(bio_out, "<NONE>");
                BIO_printf(bio_out, "\n");
            }
            if (hash == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
#ifndef OPENSSL_NO_MD5
            if (hash_old == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash_old(X509_CRL_get_issuer(x)));
            }
#endif
            if (lastupdate == i) {
                BIO_printf(bio_out, "lastUpdate=");
                ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x));
                BIO_printf(bio_out, "\n");
            }
            if (nextupdate == i) {
                BIO_printf(bio_out, "nextUpdate=");
                if (X509_CRL_get0_nextUpdate(x))
                    ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x));
                else
                    BIO_printf(bio_out, "NONE");
                BIO_printf(bio_out, "\n");
            }
            if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x, digest, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }
        }
    }
    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (text)
        X509_CRL_print(out, x);

    if (noout) {
        ret = 0;
        goto end;
    }

    if (outformat == FORMAT_ASN1)
        i = (int)i2d_X509_CRL_bio(out, x);
    else
        i = PEM_write_bio_X509_CRL(out, x);
    if (!i) {
        BIO_printf(bio_err, "unable to write CRL\n");
        goto end;
    }
    ret = 0;

 end:
    if (ret != 0)
        ERR_print_errors(bio_err);
    BIO_free_all(out);
    X509_CRL_free(x);
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(store);
    return (ret);
}
Пример #8
0
int MAIN(int argc, char **argv)
{
    unsigned long nmflag = 0;
    X509_CRL *x = NULL;
    char *CAfile = NULL, *CApath = NULL;
    int ret = 1, i, num, badops = 0, badsig = 0;
    BIO *out = NULL;
    int informat, outformat, keyformat;
    char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
    int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout =
        0, text = 0;
#ifndef OPENSSL_NO_MD5
    int hash_old = 0;
#endif
    int fingerprint = 0, crlnumber = 0;
    const char **pp;
    X509_STORE *store = NULL;
    X509_STORE_CTX ctx;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    int do_ver = 0;
    const EVP_MD *md_alg, *digest = EVP_sha1();

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

    if (bio_out == NULL)
        if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
            BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
            {
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
                bio_out = BIO_push(tmpbio, bio_out);
            }
#endif
        }

    informat = FORMAT_PEM;
    outformat = FORMAT_PEM;
    keyformat = FORMAT_PEM;

    argc--;
    argv++;
    num = 0;
    while (argc >= 1) {
#ifdef undef
        if (sgx_strcmp(*argv, "-p") == 0) {
            if (--argc < 1)
                goto bad;
            if (!args_from_file(++argv, Nargc, Nargv)) {
                goto end;
            }
        */}
#endif
        if (sgx_strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-outform") == 0) {
            if (--argc < 1)
                goto bad;
            outformat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (sgx_strcmp(*argv, "-gendelta") == 0) {
            if (--argc < 1)
                goto bad;
            crldiff = *(++argv);
        } else if (sgx_strcmp(*argv, "-key") == 0) {
            if (--argc < 1)
                goto bad;
            keyfile = *(++argv);
        } else if (sgx_strcmp(*argv, "-keyform") == 0) {
            if (--argc < 1)
                goto bad;
            keyformat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            outfile = *(++argv);
        } else if (sgx_strcmp(*argv, "-CApath") == 0) {
            if (--argc < 1)
                goto bad;
            CApath = *(++argv);
            do_ver = 1;
        } else if (sgx_strcmp(*argv, "-CAfile") == 0) {
            if (--argc < 1)
                goto bad;
            CAfile = *(++argv);
            do_ver = 1;
        } else if (sgx_strcmp(*argv, "-verify") == 0)
            do_ver = 1;
        else if (sgx_strcmp(*argv, "-text") == 0)
            text = 1;
        else if (sgx_strcmp(*argv, "-hash") == 0)
            hash = ++num;
#ifndef OPENSSL_NO_MD5
        else if (sgx_strcmp(*argv, "-hash_old") == 0)
            hash_old = ++num;
#endif
        else if (sgx_strcmp(*argv, "-nameopt") == 0) {
            if (--argc < 1)
                goto bad;
            if (!set_name_ex(&nmflag, *(++argv)))
                goto bad;
        } else if (sgx_strcmp(*argv, "-issuer") == 0)
            issuer = ++num;
        else if (sgx_strcmp(*argv, "-lastupdate") == 0)
            lastupdate = ++num;
        else if (sgx_strcmp(*argv, "-nextupdate") == 0)
            nextupdate = ++num;
        else if (sgx_strcmp(*argv, "-noout") == 0)
            noout = ++num;
        else if (sgx_strcmp(*argv, "-fingerprint") == 0)
            fingerprint = ++num;
        else if (sgx_strcmp(*argv, "-crlnumber") == 0)
            crlnumber = ++num;
        else if (sgx_strcmp(*argv, "-badsig") == 0)
            badsig = 1;
        else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
            /* ok */
            digest = md_alg;
        } else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        for (pp = crl_usage; (*pp != NULL); pp++)
            BIO_printf(bio_err, "%s", *pp);
        goto end;
    }

    ERR_load_crypto_strings();
    x = load_crl(infile, informat);
    if (x == NULL) {
        goto end;
    }

    if (do_ver) {
        store = X509_STORE_new();
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        if (lookup == NULL)
            goto end;
        if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM))
            X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);

        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
        if (lookup == NULL)
            goto end;
        if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM))
            X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
        ERR_clear_error();

        if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
            BIO_printf(bio_err, "Error initialising X509 store\n");
            goto end;
        }

        i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
                                      X509_CRL_get_issuer(x), &xobj);
        if (i <= 0) {
            BIO_printf(bio_err, "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get_pubkey(xobj.data.x509);
        X509_OBJECT_free_contents(&xobj);
        if (!pkey) {
            BIO_printf(bio_err, "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0)
            goto end;
        if (i == 0)
            BIO_printf(bio_err, "verify failure\n");
        else
            BIO_printf(bio_err, "verify OK\n");
    }

    if (crldiff) {
        X509_CRL *newcrl, *delta;
        if (!keyfile) {
            BIO_puts(bio_err, "Missing CRL signing key\n");
            goto end;
        }
        newcrl = load_crl(crldiff, informat);
        if (!newcrl)
            goto end;
        pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL,
                        "CRL signing key");
        if (!pkey) {
            X509_CRL_free(newcrl);
            goto end;
        }
        delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
        X509_CRL_free(newcrl);
        EVP_PKEY_free(pkey);
        if (delta) {
            X509_CRL_free(x);
            x = delta;
        } else {
            BIO_puts(bio_err, "Error creating delta CRL\n");
            goto end;
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
                           nmflag);
            }
            if (crlnumber == i) {
                ASN1_INTEGER *crlnum;
                crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL);
                BIO_printf(bio_out, "crlNumber=");
                if (crlnum) {
                    i2a_ASN1_INTEGER(bio_out, crlnum);
                    ASN1_INTEGER_free(crlnum);
                } else
                    BIO_puts(bio_out, "<NONE>");
                BIO_printf(bio_out, "\n");
            }
            if (hash == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
#ifndef OPENSSL_NO_MD5
            if (hash_old == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash_old(X509_CRL_get_issuer(x)));
            }
#endif
            if (lastupdate == i) {
                BIO_printf(bio_out, "lastUpdate=");
                ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x));
                BIO_printf(bio_out, "\n");
            }
            if (nextupdate == i) {
                BIO_printf(bio_out, "nextUpdate=");
                if (X509_CRL_get_nextUpdate(x))
                    ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x));
                else
                    BIO_printf(bio_out, "NONE");
                BIO_printf(bio_out, "\n");
            }
            if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x, digest, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }
        }
    }

    out = BIO_new(BIO_s_file());
    if (out == NULL) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
#endif
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            goto end;
        }
    }

    if (text)
        X509_CRL_print(out, x);

    if (noout) {
        ret = 0;
        goto end;
    }

    if (badsig)
        x->signature->data[x->signature->length - 1] ^= 0x1;

    if (outformat == FORMAT_ASN1)
        i = (int)i2d_X509_CRL_bio(out, x);
    else if (outformat == FORMAT_PEM)
        i = PEM_write_bio_X509_CRL(out, x);
    else {
        BIO_printf(bio_err, "bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err, "unable to write CRL\n");
        goto end;
    }
    ret = 0;
 end:
    if (ret != 0)
        ERR_print_errors(bio_err);
    BIO_free_all(out);
    BIO_free_all(bio_out);
    bio_out = NULL;
    X509_CRL_free(x);
    if (store) {
        X509_STORE_CTX_cleanup(&ctx);
        X509_STORE_free(store);
    }
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Пример #9
0
int
crl_main(int argc, char **argv)
{
	unsigned long nmflag = 0;
	X509_CRL *x = NULL;
	int ret = 1, i;
	BIO *out = NULL;
	X509_STORE *store = NULL;
	X509_STORE_CTX ctx;
	X509_LOOKUP *lookup = NULL;
	X509_OBJECT xobj;
	EVP_PKEY *pkey;
	const EVP_MD *digest;
	char *digest_name = NULL;

	if (single_execution) {
		if (pledge("stdio cpath wpath rpath", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	if (bio_out == NULL) {
		if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
			BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
		}
	}

	digest = EVP_sha256();

	memset(&crl_config, 0, sizeof(crl_config));
	crl_config.informat = FORMAT_PEM;
	crl_config.outformat = FORMAT_PEM;

	if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
		crl_usage();
		goto end;
	}

	if (crl_config.cafile != NULL || crl_config.capath != NULL)
		crl_config.verify = 1;

	if (crl_config.nameopt != NULL) {
		if (set_name_ex(&nmflag, crl_config.nameopt) != 1) {
			fprintf(stderr,
			    "Invalid -nameopt argument '%s'\n",
			    crl_config.nameopt);
			goto end;
		}
	}

	if (digest_name != NULL) {
		if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
			fprintf(stderr,
			    "Unknown message digest algorithm '%s'\n",
			    digest_name);
			goto end;
		}
	}

	x = load_crl(crl_config.infile, crl_config.informat);
	if (x == NULL)
		goto end;

	if (crl_config.verify) {
		store = X509_STORE_new();
		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_load_file(lookup, crl_config.cafile,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_load_file(lookup, NULL,
			    X509_FILETYPE_DEFAULT);

		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_add_dir(lookup, crl_config.capath,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_add_dir(lookup, NULL,
			    X509_FILETYPE_DEFAULT);
		ERR_clear_error();

		if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
			BIO_printf(bio_err,
			    "Error initialising X509 store\n");
			goto end;
		}
		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
		    X509_CRL_get_issuer(x), &xobj);
		if (i <= 0) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer certificate\n");
			goto end;
		}
		pkey = X509_get_pubkey(xobj.data.x509);
		X509_OBJECT_free_contents(&xobj);
		if (!pkey) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer public key\n");
			goto end;
		}
		i = X509_CRL_verify(x, pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			goto end;
		if (i == 0)
			BIO_printf(bio_err, "verify failure\n");
		else
			BIO_printf(bio_err, "verify OK\n");
	}

	/* Print requested information the order that the flags were given. */
	for (i = 1; i <= argc; i++) {
		if (crl_config.issuer == i) {
			print_name(bio_out, "issuer=",
			    X509_CRL_get_issuer(x), nmflag);
		}
		if (crl_config.crlnumber == i) {
			ASN1_INTEGER *crlnum;
			crlnum = X509_CRL_get_ext_d2i(x,
			    NID_crl_number, NULL, NULL);
			BIO_printf(bio_out, "crlNumber=");
			if (crlnum) {
				i2a_ASN1_INTEGER(bio_out, crlnum);
				ASN1_INTEGER_free(crlnum);
			} else
				BIO_puts(bio_out, "<NONE>");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.hash == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash(X509_CRL_get_issuer(x)));
		}
#ifndef OPENSSL_NO_MD5
		if (crl_config.hash_old == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash_old(X509_CRL_get_issuer(x)));
		}
#endif
		if (crl_config.lastupdate == i) {
			BIO_printf(bio_out, "lastUpdate=");
			ASN1_TIME_print(bio_out,
			    X509_CRL_get_lastUpdate(x));
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.nextupdate == i) {
			BIO_printf(bio_out, "nextUpdate=");
			if (X509_CRL_get_nextUpdate(x))
				ASN1_TIME_print(bio_out,
				    X509_CRL_get_nextUpdate(x));
			else
				BIO_printf(bio_out, "NONE");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.fingerprint == i) {
			int j;
			unsigned int n;
			unsigned char md[EVP_MAX_MD_SIZE];

			if (!X509_CRL_digest(x, digest, md, &n)) {
				BIO_printf(bio_err, "out of memory\n");
				goto end;
			}
			BIO_printf(bio_out, "%s Fingerprint=",
			    OBJ_nid2sn(EVP_MD_type(digest)));
			for (j = 0; j < (int) n; j++) {
				BIO_printf(bio_out, "%02X%c", md[j],
				    (j + 1 == (int)n) ? '\n' : ':');
			}
		}
	}

	out = BIO_new(BIO_s_file());
	if (out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (crl_config.outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, crl_config.outfile) <= 0) {
			perror(crl_config.outfile);
			goto end;
		}
	}

	if (crl_config.text)
		X509_CRL_print(out, x);

	if (crl_config.noout) {
		ret = 0;
		goto end;
	}
	if (crl_config.outformat == FORMAT_ASN1)
		i = (int) i2d_X509_CRL_bio(out, x);
	else if (crl_config.outformat == FORMAT_PEM)
		i = PEM_write_bio_X509_CRL(out, x);
	else {
		BIO_printf(bio_err,
		    "bad output format specified for outfile\n");
		goto end;
	}
	if (!i) {
		BIO_printf(bio_err, "unable to write CRL\n");
		goto end;
	}
	ret = 0;

 end:
	BIO_free_all(out);
	BIO_free_all(bio_out);
	bio_out = NULL;
	X509_CRL_free(x);
	if (store) {
		X509_STORE_CTX_cleanup(&ctx);
		X509_STORE_free(store);
	}

	return (ret);
}