Exemplo n.º 1
0
static int file_read_pem(BIO *bp, char **pem_name, char **pem_header,
                         unsigned char **data, long *len,
                         const UI_METHOD *ui_method,
                         void *ui_data, int secure)
{
    int i = secure
        ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len,
                          PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE)
        : PEM_read_bio(bp, pem_name, pem_header, data, len);

    if (i <= 0)
        return 0;

    /*
     * 10 is the number of characters in "Proc-Type:", which
     * PEM_get_EVP_CIPHER_INFO() requires to be present.
     * If the PEM header has less characters than that, it's
     * not worth spending cycles on it.
     */
    if (strlen(*pem_header) > 10) {
        EVP_CIPHER_INFO cipher;
        struct pem_pass_data pass_data;

        if (!PEM_get_EVP_CIPHER_INFO(*pem_header, &cipher)
            || !file_fill_pem_pass_data(&pass_data, "PEM", ui_method, ui_data)
            || !PEM_do_header(&cipher, *data, len, file_get_pem_pass,
                              &pass_data)) {
            return 0;
        }
    }
    return 1;
}
Exemplo n.º 2
0
void openssl_rsa_pemkey()
{
	long len;
	BIGNUM *bne;
	BIO *ins, *outs;
	RSA *r, *read;
	char *name, *head;
	unsigned char *data;
	const EVP_CIPHER *enc;
	EVP_CIPHER_INFO cipher;

	OpenSSL_add_all_algorithms();

	bne = BN_new();
	BN_set_word(bne, RSA_3);
	r = RSA_new();
	RSA_generate_key_ex(r, LINE_LEN, bne, NULL);

	enc = EVP_des_ede3_ofb();
	outs = BIO_new_file("/tmp/pri.pem", "w");
	PEM_write_bio_RSAPrivateKey(outs, r, enc, NULL, 0, NULL, "beike2012");
	BIO_free(outs);

	outs = BIO_new_file("/tmp/pub.pem", "w");
	PEM_write_bio_RSAPublicKey(outs, r);
	BIO_free(outs);

	ins = BIO_new_file("/tmp/pri.pem", "rb");
	r = RSA_new();
	read = PEM_read_bio_RSAPrivateKey(ins, &r, NULL, "beike2012");
	if (read->d == NULL) {
		printf("PEM_read_bio_RSAPrivateKey err!\n");
		return;
	}

	printf("\nEVP_CIPHER_INFO:\n");
	while (1) {
		if (PEM_read_bio(ins, &name, &head, &data, &len) == 0)
			break;

		if (strlen(head) > 0) {
			PEM_get_EVP_CIPHER_INFO(head, &cipher);
			if (PEM_do_header(&cipher, data, &len, NULL, NULL) == 0)
				return;
			printf("name=%s, head=%s, data=%s\n", name, head, data);
		}

		OPENSSL_free(name);
		OPENSSL_free(head);
		OPENSSL_free(data);
	}

	RSA_free(read);
	BIO_free(ins);
}
Exemplo n.º 3
0
bool
crypto_pem_decode(const char *name, struct buffer *dst,
                  const struct buffer *src)
{
    bool ret = false;

    BIO *bio = BIO_new_mem_buf((char *)BPTR(src), BLEN(src));
    if (!bio)
    {
        crypto_msg(M_FATAL, "Cannot open memory BIO for PEM decode");
    }

    char *name_read = NULL;
    char *header_read = NULL;
    uint8_t *data_read = NULL;
    long data_read_len = 0;
    if (!PEM_read_bio(bio, &name_read, &header_read, &data_read,
                      &data_read_len))
    {
        dmsg(D_CRYPT_ERRORS, "%s: PEM decode failed", __func__);
        goto cleanup;
    }

    if (strcmp(name, name_read))
    {
        dmsg(D_CRYPT_ERRORS,
             "%s: unexpected PEM name (got '%s', expected '%s')",
             __func__, name_read, name);
        goto cleanup;
    }

    uint8_t *dst_data = buf_write_alloc(dst, data_read_len);
    if (!dst_data)
    {
        dmsg(D_CRYPT_ERRORS, "%s: dst too small (%i, needs %li)", __func__,
             BCAP(dst), data_read_len);
        goto cleanup;
    }
    memcpy(dst_data, data_read, data_read_len);

    ret = true;
cleanup:
    OPENSSL_free(name_read);
    OPENSSL_free(header_read);
    OPENSSL_free(data_read);
    if (!BIO_free(bio))
    {
        ret = false;;
    }

    return ret;
}
Exemplo n.º 4
0
int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
             long *len)
{
    BIO *b;
    int ret;

    if ((b = BIO_new(BIO_s_file())) == NULL) {
        PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
        return 0;
    }
    BIO_set_fp(b, fp, BIO_NOCLOSE);
    ret = PEM_read_bio(b, name, header, data, len);
    BIO_free(b);
    return ret;
}
Exemplo n.º 5
0
int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
	     long *len)
        {
        BIO *b;
        int ret;

        if ((b=BIO_new(BIO_s_file())) == NULL)
		{
		OPENSSL_PUT_ERROR(PEM, PEM_read, ERR_R_BUF_LIB);
                return(0);
		}
        BIO_set_fp(b,fp,BIO_NOCLOSE);
        ret=PEM_read_bio(b, name, header, data,len);
        BIO_free(b);
        return(ret);
        }
Exemplo n.º 6
0
int
PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
    const char *name, BIO *bp, pem_password_cb *cb, void *u)
{
	EVP_CIPHER_INFO cipher;
	char *nm = NULL, *header = NULL;
	unsigned char *data = NULL;
	long len;
	int ret = 0;

	for (;;) {
		if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
			if (ERR_GET_REASON(ERR_peek_error()) ==
			    PEM_R_NO_START_LINE)
				ERR_asprintf_error_data("Expecting: %s", name);
			return 0;
		}
		if (check_pem(nm, name))
			break;
		free(nm);
		free(header);
		free(data);
	}
	if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
		goto err;
	if (!PEM_do_header(&cipher, data, &len, cb, u))
		goto err;

	*pdata = data;
	*plen = len;

	if (pnm)
		*pnm = nm;

	ret = 1;

err:
	if (!ret || !pnm)
		free(nm);
	free(header);
	if (!ret)
		free(data);
	return ret;
}
Exemplo n.º 7
0
int MAIN(int argc, char **argv)
{
    int i, badops = 0, offset = 0, ret = 1, j;
    unsigned int length = 0;
    long num, tmplen;
    BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
    int informat, indent = 0, noout = 0, dump = 0, strictpem = 0;
    char *infile = NULL, *str = NULL, *prog, *oidfile = NULL, *derfile =
        NULL, *name = NULL, *header = NULL;
    char *genstr = NULL, *genconf = NULL;
    unsigned char *tmpbuf;
    const unsigned char *ctmpbuf;
    BUF_MEM *buf = NULL;
    STACK_OF(OPENSSL_STRING) *osk = NULL;
    ASN1_TYPE *at = NULL;

    informat = FORMAT_PEM;

    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;

    prog = argv[0];
    argc--;
    argv++;
    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    while (argc >= 1) {
        if (strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = 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;
            derfile = *(++argv);
        } else if (strcmp(*argv, "-i") == 0) {
            indent = 1;
        } else if (strcmp(*argv, "-noout") == 0)
            noout = 1;
        else if (strcmp(*argv, "-oid") == 0) {
            if (--argc < 1)
                goto bad;
            oidfile = *(++argv);
        } else if (strcmp(*argv, "-offset") == 0) {
            if (--argc < 1)
                goto bad;
            offset = atoi(*(++argv));
        } else if (strcmp(*argv, "-length") == 0) {
            if (--argc < 1)
                goto bad;
            length = atoi(*(++argv));
            if (length == 0)
                goto bad;
        } else if (strcmp(*argv, "-dump") == 0) {
            dump = -1;
        } else if (strcmp(*argv, "-dlimit") == 0) {
            if (--argc < 1)
                goto bad;
            dump = atoi(*(++argv));
            if (dump <= 0)
                goto bad;
        } else if (strcmp(*argv, "-strparse") == 0) {
            if (--argc < 1)
                goto bad;
            sk_OPENSSL_STRING_push(osk, *(++argv));
        } else if (strcmp(*argv, "-genstr") == 0) {
            if (--argc < 1)
                goto bad;
            genstr = *(++argv);
        } else if (strcmp(*argv, "-genconf") == 0) {
            if (--argc < 1)
                goto bad;
            genconf = *(++argv);
        } else if (strcmp(*argv, "-strictpem") == 0) {
            strictpem = 1;
            informat = FORMAT_PEM;
        } else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        BIO_printf(bio_err, "%s [options] <infile\n", prog);
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
        BIO_printf(bio_err, " -in arg       input file\n");
        BIO_printf(bio_err,
                   " -out arg      output file (output format is always DER\n");
        BIO_printf(bio_err, " -noout arg    don't produce any output\n");
        BIO_printf(bio_err, " -offset arg   offset into file\n");
        BIO_printf(bio_err, " -length arg   length of section in file\n");
        BIO_printf(bio_err, " -i            indent entries\n");
        BIO_printf(bio_err, " -dump         dump unknown data in hex form\n");
        BIO_printf(bio_err,
                   " -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
        BIO_printf(bio_err, " -oid file     file of extra oid definitions\n");
        BIO_printf(bio_err, " -strparse offset\n");
        BIO_printf(bio_err,
                   "               a series of these can be used to 'dig' into multiple\n");
        BIO_printf(bio_err, "               ASN1 blob wrappings\n");
        BIO_printf(bio_err,
                   " -genstr str   string to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -genconf file file to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -strictpem    do not attempt base64 decode outside PEM markers (-inform \n");
        BIO_printf(bio_err, "               will be ignored)\n");
        goto end;
    }

    ERR_load_crypto_strings();

    in = BIO_new(BIO_s_file());
    out = BIO_new(BIO_s_file());
    if ((in == NULL) || (out == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
#ifdef OPENSSL_SYS_VMS
    {
        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        out = BIO_push(tmpbio, out);
    }
#endif

    if (oidfile != NULL) {
        if (BIO_read_filename(in, oidfile) <= 0) {
            BIO_printf(bio_err, "problems opening %s\n", oidfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        OBJ_create_objects(in);
    }

    if (infile == NULL)
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
    else {
        if (BIO_read_filename(in, infile) <= 0) {
            perror(infile);
            goto end;
        }
    }

    if (derfile) {
        if (!(derout = BIO_new_file(derfile, "wb"))) {
            BIO_printf(bio_err, "problems opening %s\n", derfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (strictpem) {
        if (PEM_read_bio(in, &name, &header, (unsigned char **)&str, &num) !=
            1) {
            BIO_printf(bio_err, "Error reading PEM file\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    } else {

        if ((buf = BUF_MEM_new()) == NULL)
            goto end;
        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
            goto end;           /* Pre-allocate :-) */

        if (genstr || genconf) {
            num = do_generate(bio_err, genstr, genconf, buf);
            if (num < 0) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        else {

            if (informat == FORMAT_PEM) {
                BIO *tmp;

                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
                    goto end;
                BIO_push(b64, in);
                tmp = in;
                in = b64;
                b64 = tmp;
            }

            num = 0;
            for (;;) {
                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
                    goto end;
                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
                if (i <= 0)
                    break;
                num += i;
            }
        }
        str = buf->data;

    }

    /* If any structs to parse go through in sequence */

    if (sk_OPENSSL_STRING_num(osk)) {
        tmpbuf = (unsigned char *)str;
        tmplen = num;
        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
            ASN1_TYPE *atmp;
            int typ;
            j = atoi(sk_OPENSSL_STRING_value(osk, i));
            if (j == 0) {
                BIO_printf(bio_err, "'%s' is an invalid number\n",
                           sk_OPENSSL_STRING_value(osk, i));
                continue;
            }
            tmpbuf += j;
            tmplen -= j;
            atmp = at;
            ctmpbuf = tmpbuf;
            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
            ASN1_TYPE_free(atmp);
            if (!at) {
                BIO_printf(bio_err, "Error parsing structure\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            typ = ASN1_TYPE_get(at);
            if ((typ == V_ASN1_OBJECT)
                || (typ == V_ASN1_NULL)) {
                BIO_printf(bio_err, "Can't parse %s type\n",
                           typ == V_ASN1_NULL ? "NULL" : "OBJECT");
                ERR_print_errors(bio_err);
                goto end;
            }
            /* hmm... this is a little evil but it works */
            tmpbuf = at->value.asn1_string->data;
            tmplen = at->value.asn1_string->length;
        }
        str = (char *)tmpbuf;
        num = tmplen;
    }

    if (offset >= num) {
        BIO_printf(bio_err, "Error: offset too large\n");
        goto end;
    }

    num -= offset;

    if ((length == 0) || ((long)length > num))
        length = (unsigned int)num;
    if (derout) {
        if (BIO_write(derout, str + offset, length) != (int)length) {
            BIO_printf(bio_err, "Error writing output\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    if (!noout &&
        !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length,
                         indent, dump)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(derout);
    BIO_free(in);
    BIO_free_all(out);
    BIO_free(b64);
    if (ret != 0)
        ERR_print_errors(bio_err);
    if (buf != NULL)
        BUF_MEM_free(buf);
    if (name != NULL)
        OPENSSL_free(name);
    if (header != NULL)
        OPENSSL_free(header);
    if (strictpem && str != NULL)
        OPENSSL_free(str);
    if (at != NULL)
        ASN1_TYPE_free(at);
    if (osk != NULL)
        sk_OPENSSL_STRING_free(osk);
    OBJ_cleanup();
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemplo n.º 8
0
static int test_certs(BIO *fp)
{
    int count;
    char *name = 0;
    char *header = 0;
    unsigned char *data = 0;
    long len;
    typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long);
    typedef int (*i2d_X509_t)(X509 *, unsigned char **);
    int err = 0;

    for (count = 0;
         !err && PEM_read_bio(fp, &name, &header, &data, &len);
	 ++count) {
        int trusted = strcmp(name, PEM_STRING_X509_TRUSTED) == 0;
        d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509;
        i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509;
        X509 *cert = NULL;
	const unsigned char *p = data;
        unsigned char *buf = NULL;
        unsigned char *bufp;
        long enclen;

	if (!trusted
            && strcmp(name, PEM_STRING_X509) != 0
	    && strcmp(name, PEM_STRING_X509_OLD) != 0) {
	    fprintf(stderr, "unexpected PEM object: %s\n", name);
            err = 1;
	    goto next;
        }
        cert = d2i(NULL, &p, len);

        if (cert == NULL || (p - data) != len) {
	    fprintf(stderr, "error parsing input %s\n", name);
            err = 1;
            goto next;
        }

        /* Test traditional 2-pass encoding into caller allocated buffer */
        enclen = i2d(cert, NULL);
        if (len != enclen) {
	    fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
                    enclen, name, len);
            err = 1;
            goto next;
        }
        if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
            perror("malloc");
            err = 1;
            goto next;
        }
        enclen = i2d(cert, &bufp);
        if (len != enclen) {
	    fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
                    enclen, name, len);
            err = 1;
            goto next;
        }
        enclen = (long) (bufp - buf);
        if (enclen != len) {
	    fprintf(stderr, "unexpected buffer position after encoding %s\n",
                    name);
            err = 1;
            goto next;
        }
        if (memcmp(buf, data, len) != 0) {
	    fprintf(stderr, "encoded content of %s does not match input\n",
                    name);
            err = 1;
            goto next;
        }
        OPENSSL_free(buf);
        buf = NULL;

        /* Test 1-pass encoding into library allocated buffer */
        enclen = i2d(cert, &buf);
        if (len != enclen) {
	    fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
                    enclen, name, len);
            err = 1;
            goto next;
        }
        if (memcmp(buf, data, len) != 0) {
	    fprintf(stderr, "encoded content of %s does not match input\n",
                    name);
            err = 1;
            goto next;
        }

        if (trusted) {
            /* Encode just the cert and compare with initial encoding */
            OPENSSL_free(buf);
            buf = NULL;

            /* Test 1-pass encoding into library allocated buffer */
            enclen = i2d(cert, &buf);
            if (enclen > len) {
                fprintf(stderr, "encoded length %ld of %s > input length %ld\n",
                        enclen, name, len);
                err = 1;
                goto next;
            }
            if (memcmp(buf, data, enclen) != 0) {
                fprintf(stderr, "encoded cert content does not match input\n");
                err = 1;
                goto next;
            }
        }

	/*
	 * If any of these were null, PEM_read() would have failed.
	 */
    next:
        X509_free(cert);
        OPENSSL_free(buf);
	OPENSSL_free(name);
	OPENSSL_free(header);
	OPENSSL_free(data);
    }

    if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
        /* Reached end of PEM file */
        if (count > 0) {
            ERR_clear_error();
            return 1;
        }
    }

    /* Some other PEM read error */
    print_errors();
    return 0;
}
Exemplo n.º 9
0
static STACK_OF(X509) *load_chain(const char *chainfile)
{
    BIO *bp;
    char *name = 0;
    char *header = 0;
    unsigned char *data = 0;
    long len;
    int count;
    char *errtype = 0;		/* if error: cert or pkey? */
    STACK_OF(X509) *chain;
    typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long);

    if ((chain = sk_X509_new_null()) == 0) {
	perror("malloc");
	exit(1);
    }

    /*
     * On each call, PEM_read() wraps a stdio file in a BIO_NOCLOSE bio,
     * calls PEM_read_bio() and then frees the bio.  It is just as easy to
     * open a BIO as a stdio file, so we use BIOs and call PEM_read_bio()
     * directly.
     */
    if ((bp = BIO_new_file(chainfile, "r")) == NULL) {
	fprintf(stderr, "error opening chainfile: %s: %m\n", chainfile);
	exit(1);
    }
    /* Don't report old news */
    ERR_clear_error();

    for (count = 0;
	 errtype == 0 && PEM_read_bio(bp, &name, &header, &data, &len);
	 ++count) {
	const unsigned char *p = data;

	if (strcmp(name, PEM_STRING_X509) == 0
	    || strcmp(name, PEM_STRING_X509_TRUSTED) == 0
	    || strcmp(name, PEM_STRING_X509_OLD) == 0) {
	    d2i_X509_t d = strcmp(name, PEM_STRING_X509_TRUSTED) ?
		d2i_X509_AUX : d2i_X509;
	    X509 *cert = d(0, &p, len);

	    if (cert == 0 || (p - data) != len)
		errtype = "certificate";
	    else if (sk_X509_push(chain, cert) == 0) {
		perror("malloc");
		exit(1);
	    }
	} else {
	    fprintf(stderr, "unexpected chain file object: %s\n", name);
	    exit(1);
	}

	/*
	 * If any of these were null, PEM_read() would have failed.
	 */
	OPENSSL_free(name);
	OPENSSL_free(header);
	OPENSSL_free(data);
    }
    BIO_free(bp);

    if (errtype) {
	print_errors();
	fprintf(stderr, "error reading: %s: malformed %s", chainfile, errtype);
	exit(1);
    }
    if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
	/* Reached end of PEM file */
	ERR_clear_error();
	if (count > 0)
	    return chain;
	fprintf(stderr, "no certificates found in: %s\n", chainfile);
	exit(1);
    }
    /* Some other PEM read error */
    print_errors();
    fprintf(stderr, "error reading: %s\n", chainfile);
    exit(1);
}
Exemplo n.º 10
0
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
	{
	unsigned char *serverinfo = NULL;
	size_t serverinfo_length = 0;
	unsigned char* extension = 0;
	long extension_length = 0;
	char* name = NULL;
	char* header = NULL;
	char namePrefix[] = "SERVERINFO FOR ";
	int ret = 0;
	BIO *bin = NULL;
	size_t num_extensions = 0;

	if (ctx == NULL || file == NULL)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,ERR_R_PASSED_NULL_PARAMETER);
		goto end;
		}

	bin = BIO_new(BIO_s_file_internal());
	if (bin == NULL)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
		goto end;
		}
	if (BIO_read_filename(bin, file) <= 0)
		{
		SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
		goto end;
		}

	for (num_extensions=0;; num_extensions++)
		{
		if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) == 0)
			{
			/* There must be at least one extension in this file */
			if (num_extensions == 0)
				{
				SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_NO_PEM_EXTENSIONS);
				goto end;
				}
			else /* End of file, we're done */
				break;
			}
		/* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
		if (strlen(name) < strlen(namePrefix))
			{
			SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT);
			goto end;
			}
		if (strncmp(name, namePrefix, strlen(namePrefix)) != 0)
			{
			SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_BAD_PREFIX);
			goto end;
			}
		/* Check that the decoded PEM data is plausible (valid length field) */
		if (extension_length < 4 || (extension[2] << 8) + extension[3] != extension_length - 4)
			{
			SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
			goto end;
			}
		/* Append the decoded extension to the serverinfo buffer */
		serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
		if (serverinfo == NULL)
			{
			SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
			goto end;
			}
		memcpy(serverinfo + serverinfo_length, extension, extension_length);
		serverinfo_length += extension_length;

		OPENSSL_free(name); name = NULL;
		OPENSSL_free(header); header = NULL;
		OPENSSL_free(extension); extension = NULL;
		}

	ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
end:
	/* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
	OPENSSL_free(name);
	OPENSSL_free(header);
	OPENSSL_free(extension);
	OPENSSL_free(serverinfo);
	if (bin != NULL)
		BIO_free(bin);
	return ret;
	}
Exemplo n.º 11
0
int asn1parse_main(int argc, char **argv)
{
    ASN1_TYPE *at = NULL;
    BIO *in = NULL, *b64 = NULL, *derout = NULL;
    BUF_MEM *buf = NULL;
    STACK_OF(OPENSSL_STRING) *osk = NULL;
    char *genstr = NULL, *genconf = NULL;
    char *infile = NULL, *oidfile = NULL, *derfile = NULL;
    unsigned char *str = NULL;
    char *name = NULL, *header = NULL, *prog;
    const unsigned char *ctmpbuf;
    int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM;
    int offset = 0, ret = 1, i, j;
    long num, tmplen;
    unsigned char *tmpbuf;
    unsigned int length = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, asn1parse_options);

    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
        BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
        goto end;
    }

    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(asn1parse_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_OUT:
            derfile = opt_arg();
            break;
        case OPT_INDENT:
            indent = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_OID:
            oidfile = opt_arg();
            break;
        case OPT_OFFSET:
            offset = strtol(opt_arg(), NULL, 0);
            break;
        case OPT_LENGTH:
            length = atoi(opt_arg());
            break;
        case OPT_DUMP:
            dump = -1;
            break;
        case OPT_DLIMIT:
            dump = atoi(opt_arg());
            break;
        case OPT_STRPARSE:
            sk_OPENSSL_STRING_push(osk, opt_arg());
            break;
        case OPT_GENSTR:
            genstr = opt_arg();
            break;
        case OPT_GENCONF:
            genconf = opt_arg();
            break;
        case OPT_STRICTPEM:
            strictpem = 1;
            informat = FORMAT_PEM;
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (oidfile != NULL) {
        in = bio_open_default(oidfile, 'r', FORMAT_TEXT);
        if (in == NULL)
            goto end;
        OBJ_create_objects(in);
        BIO_free(in);
    }

    if ((in = bio_open_default(infile, 'r', informat)) == NULL)
        goto end;

    if (derfile && (derout = bio_open_default(derfile, 'w', FORMAT_ASN1)) == NULL)
        goto end;

    if (strictpem) {
        if (PEM_read_bio(in, &name, &header, &str, &num) !=
            1) {
            BIO_printf(bio_err, "Error reading PEM file\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    } else {

        if ((buf = BUF_MEM_new()) == NULL)
            goto end;
        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
            goto end;           /* Pre-allocate :-) */

        if (genstr || genconf) {
            num = do_generate(genstr, genconf, buf);
            if (num < 0) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        else {

            if (informat == FORMAT_PEM) {
                BIO *tmp;

                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
                    goto end;
                BIO_push(b64, in);
                tmp = in;
                in = b64;
                b64 = tmp;
            }

            num = 0;
            for (;;) {
                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
                    goto end;
                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
                if (i <= 0)
                    break;
                num += i;
            }
        }
        str = (unsigned char *)buf->data;

    }

    /* If any structs to parse go through in sequence */

    if (sk_OPENSSL_STRING_num(osk)) {
        tmpbuf = str;
        tmplen = num;
        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
            ASN1_TYPE *atmp;
            int typ;
            j = atoi(sk_OPENSSL_STRING_value(osk, i));
            if (j == 0) {
                BIO_printf(bio_err, "'%s' is an invalid number\n",
                           sk_OPENSSL_STRING_value(osk, i));
                continue;
            }
            tmpbuf += j;
            tmplen -= j;
            atmp = at;
            ctmpbuf = tmpbuf;
            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
            ASN1_TYPE_free(atmp);
            if (!at) {
                BIO_printf(bio_err, "Error parsing structure\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            typ = ASN1_TYPE_get(at);
            if ((typ == V_ASN1_OBJECT)
                || (typ == V_ASN1_BOOLEAN)
                || (typ == V_ASN1_NULL)) {
                BIO_printf(bio_err, "Can't parse %s type\n", ASN1_tag2str(typ));
                ERR_print_errors(bio_err);
                goto end;
            }
            /* hmm... this is a little evil but it works */
            tmpbuf = at->value.asn1_string->data;
            tmplen = at->value.asn1_string->length;
        }
        str = tmpbuf;
        num = tmplen;
    }

    if (offset >= num) {
        BIO_printf(bio_err, "Error: offset too large\n");
        goto end;
    }

    num -= offset;

    if ((length == 0) || ((long)length > num))
        length = (unsigned int)num;
    if (derout) {
        if (BIO_write(derout, str + offset, length) != (int)length) {
            BIO_printf(bio_err, "Error writing output\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    if (!noout &&
        !ASN1_parse_dump(bio_out, &(str[offset]), length,
                         indent, dump)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(derout);
    BIO_free(in);
    BIO_free(b64);
    if (ret != 0)
        ERR_print_errors(bio_err);
    BUF_MEM_free(buf);
    OPENSSL_free(name);
    OPENSSL_free(header);
    if (strictpem)
        OPENSSL_free(str);
    ASN1_TYPE_free(at);
    sk_OPENSSL_STRING_free(osk);
    return (ret);
}
Exemplo n.º 12
0
static void process_file(const char *filename)
{
	FILE *keyfile;
	int i, count;
	unsigned char buffer[LINE_BUFFER_SIZE];
	BIO *bp;
	char *nm = NULL, *header = NULL;
	unsigned char *data = NULL;
	EVP_CIPHER_INFO cipher;
	EVP_PKEY pk;
	long len;
	DSA *dsapkc = NULL;
	RSA *rsapkc = NULL;
	const char unsigned *dc;

	if (!(keyfile = fopen(filename, "rb"))) {
	    fprintf(stderr, "! %s : %s\n", filename, strerror(errno));
	    return;
	}
	/* verify input files using OpenSSL */
	bp = BIO_new(BIO_s_file());
	if(!bp) {
	    fprintf(stderr, "OpenSSL BIO allocation failure\n");
	    return;
	}
	if(!BIO_read_filename(bp, filename)) {
	    fprintf(stderr, "OpenSSL BIO_read_filename failure\n");
	    ERR_print_errors_fp(stderr);
	    return;
	}
	/* PEM_bytes_read_bio function in crypto/pem/pem_lib.c
	 * check_pem function in crypto/pem/pem_lib.c */
	for (;;) {
		if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
			if (ERR_GET_REASON(ERR_peek_error()) ==
			    PEM_R_NO_START_LINE) {
				/* ERR_print_errors_fp(stderr); */
	            fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed");
				goto out;
			}
		}
		if(!nm) {
			fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed");
			goto out;
		}
        /* only PEM encoded DSA and RSA private keys are supported. */
		if (!strcmp(nm, PEM_STRING_DSA)) {
			pk.save_type = EVP_PKEY_DSA;
			break;
		}
		if (!strcmp(nm, PEM_STRING_RSA)) {
			pk.save_type = EVP_PKEY_RSA;
			break;
		}
		OPENSSL_free(nm);
		OPENSSL_free(header);
		OPENSSL_free(data);
		BIO_free(bp);
	}
	if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) {
		ERR_print_errors_fp(stderr);
		return;
	}
	/* check if key has no password */
	dc = data;
	if (PEM_do_header(&cipher, data, &len, NULL, (char *) "")) {
		if (pk.save_type == EVP_PKEY_DSA) {
			if ((dsapkc = d2i_DSAPrivateKey(NULL, &dc, len)) != NULL) {
				fprintf(stderr, "%s has no password!\n", filename);
				DSA_free(dsapkc);
				goto out;
			}
		}
		else if (pk.save_type == EVP_PKEY_RSA) {
			if ((rsapkc = d2i_RSAPrivateKey(NULL, &dc, len)) != NULL) {
				fprintf(stderr, "%s has no password!\n", filename);
				RSA_free(rsapkc);
				goto out;
                        }
                }
        }
	/* key has been verified */
	count = fread(buffer, 1, LINE_BUFFER_SIZE, keyfile);
	printf("%s:$ssh2$", basename(filename));
	for (i = 0; i < count; i++) {
	    printf("%c%c", itoa16[ARCH_INDEX(buffer[i] >> 4)],
	            itoa16[ARCH_INDEX(buffer[i] & 0x0f)]);
	}
	printf("*%d\n", count);
out:
	fclose(keyfile);
	if(bp)
		BIO_free(bp);
}