示例#1
0
文件: cms.c 项目: Ana06/openssl
int FuzzerTestOneInput(const uint8_t *buf, size_t len)
{
    CMS_ContentInfo *cms;
    BIO *in;

    if (len == 0)
        return 0;

    in = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(in, buf, len) == len);
    cms = d2i_CMS_bio(in, NULL);
    if (cms != NULL) {
        BIO *out = BIO_new(BIO_s_null());

        i2d_CMS_bio(out, cms);
        BIO_free(out);
        CMS_ContentInfo_free(cms);
    }

    BIO_free(in);
    ERR_clear_error();

    return 0;
}
示例#2
0
int
main( int argc, char * argv [] )
{
    enum
    {
        ARG_IN_DATA_FILE_IX          = 1,
        ARG_OUT_SIG_FILE_IX          = 2,
        ARG_KEY_FILE_IX              = 3,
        ARG_KEY_PASS_IX              = 4,
        ARG_KEY_CERT_FILE_IX         = 5,
        ARG_FIRST_EXTRA_CERT_FILE_IX = 6
    };

    int exit_code = 0;

    /* -------------------------------------------------------------- */
    /* initialization */

    exit_code = 1;

    SSL_load_error_strings();
    SSL_library_init();

    /* -------------------------------------------------------------- */
    /* command-line processing */

    exit_code = 2;

    if ( argc < 6 )
    {
        fprintf( stderr, "usage: %s IN_DATA_FILE OUT_SIG_FILE"
                 " KEY_FILE KEY_PASS KEY_CERT EXTRA_CERTS...\n", argv[0] );
        return 1;
    }

    BIO * in_data_file = BIO_new_file( argv[ ARG_IN_DATA_FILE_IX ], "rb" );
    if ( ! in_data_file )
    {
        perror( argv[ ARG_IN_DATA_FILE_IX ] );
        goto end;
    }

    BIO * out_sig_file = BIO_new_file( argv[ ARG_OUT_SIG_FILE_IX ], "wb" );
    if ( ! out_sig_file )
    {
        perror( argv[ ARG_OUT_SIG_FILE_IX ] );
        goto free_in_data_file;
    }

    BIO * key_file = BIO_new_file( argv[ ARG_KEY_FILE_IX ], "rb" );
    if ( ! key_file )
    {
        perror( argv[ ARG_KEY_FILE_IX ] );
        goto free_out_sig_file;
    }

    char * pw = argv[ ARG_KEY_PASS_IX ];
    /* fprintf( stderr, "pw='%s'\n", pw ); */

    BIO * key_cert_file = BIO_new_file( argv[ ARG_KEY_CERT_FILE_IX ], "rb" );
    if ( ! key_cert_file )
    {
        perror( argv[ ARG_KEY_CERT_FILE_IX ] );
        goto free_key_file;
    }

    BIO * * extra_cert_files = NULL;
    int num_extra_cert_files = argc - ARG_FIRST_EXTRA_CERT_FILE_IX;
    if ( num_extra_cert_files > 0 )
    {
        extra_cert_files = calloc( num_extra_cert_files, sizeof( BIO * ) );
        if ( ! extra_cert_files )
        {
            perror( "extra_cert_files" );
            goto free_key_cert_file;
        }

        for ( int i = 0; i < num_extra_cert_files; ++i )
        {
            extra_cert_files[i] =
              BIO_new_file( argv[ ARG_FIRST_EXTRA_CERT_FILE_IX + i ], "rb" );
            if ( ! extra_cert_files[i] )
            {
                perror( argv[ ARG_FIRST_EXTRA_CERT_FILE_IX + i ] );
                goto free_key_cert_file;
            }
        }
    }

    /* -------------------------------------------------------------- */
    /* processing */

    exit_code = 3;

#define FAIL( msg, dest )                      \
    do {                                       \
        fprintf( stderr, "error: " msg "\n" ); \
        goto dest;                             \
    } while ( 0 )

    EVP_PKEY * key = PEM_read_bio_PrivateKey( key_file, NULL, NULL, pw );
    if ( ! key )
        FAIL( "reading private key", free_extra_cert_files );

    X509 * key_cert = PEM_read_bio_X509( key_cert_file, NULL, NULL, NULL );
    if ( ! key_cert )
        FAIL( "reading signing cert", free_key );

    STACK_OF(X509) * extra_certs = NULL;
    if ( num_extra_cert_files > 0 )
    {
        int success = 1;

        extra_certs = sk_X509_new_null();
        if ( ! extra_certs )
            FAIL( "allocating stack for extra certs", free_key_cert );

        for ( int i = 0; i < num_extra_cert_files; ++i )
        {
            X509 * tmp = PEM_read_bio_X509( extra_cert_files[i],
                                            NULL, NULL, NULL );
            if ( ! tmp )
            {
                fprintf( stderr, "error reading '%s'\n",
                         argv[ ARG_FIRST_EXTRA_CERT_FILE_IX + i ] );
                success = 0;
                break;
            }

            if ( ! sk_X509_push( extra_certs, tmp ) )
            {
                fprintf( stderr, "error pushing '%s'\n",
                         argv[ ARG_FIRST_EXTRA_CERT_FILE_IX + i ] );
                success = 0;
                X509_free( tmp );
                break;
            }
        }

        if ( ! success )
            FAIL( "could not read extra certs", free_extra_certs );
    }

    CMS_ContentInfo * ci = CMS_sign( key_cert, key, extra_certs, in_data_file,
                                     CMS_DETACHED | CMS_BINARY );

    /* if ( 1 != PEM_write_bio_CMS( out_sig_file, ci ) )
           FAIL( "could not write signature in PEM", free_ci ); */

    if ( 1 != i2d_CMS_bio( out_sig_file, ci ) )
           FAIL( "could not write signature in DER", free_ci );

    /* -------------------------------------------------------------- */
    /* success */

    exit_code = 0;

    /* -------------------------------------------------------------- */
    /* cleanup */

free_ci:
    CMS_ContentInfo_free( ci );

free_extra_certs:
    sk_X509_pop_free( extra_certs, &X509_free );

free_key_cert:
    X509_free( key_cert );

free_key:
    EVP_PKEY_free( key );

free_extra_cert_files:
    for ( int i = 0; i < num_extra_cert_files; ++i )
        BIO_vfree( extra_cert_files[ i ] );
    free( extra_cert_files );

free_key_cert_file:
    BIO_vfree( key_cert_file );

free_key_file:
    BIO_vfree( key_file );

free_out_sig_file:
    BIO_vfree( out_sig_file );

free_in_data_file:
    BIO_vfree( in_data_file );

    ERR_print_errors_fp( stderr );

    ERR_remove_state( /* pid= */ 0 );
    ENGINE_cleanup();
    CONF_modules_unload( /* all= */ 1 );
    EVP_cleanup();
    ERR_free_strings();
    CRYPTO_cleanup_all_ex_data();

end:
    return exit_code;
}
示例#3
0
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size, 
    const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
{
    PKCS12 *p12 = NULL;
    EVP_PKEY *evp_pkey = NULL;
    BUF_MEM *buf_mem = NULL;
    BIO *cert_bio = NULL;
    BIO *message_bio = NULL;
    BIO *signature_bio = NULL;
    CMS_ContentInfo *cms = NULL;
    CMS_SignerInfo *signer_info = NULL;
    STACK_OF(X509) *ca_stack = NULL;
    X509 *cert = NULL;
    int32_t result = 0;
    int32_t err = MZ_OK;


    if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
        return MZ_PARAM_ERROR;

    mz_crypt_init();

    *signature = NULL;
    *signature_size = 0;

    cert_bio = BIO_new_mem_buf(cert_data, cert_data_size);

    if (d2i_PKCS12_bio(cert_bio, &p12) == NULL)
        err = MZ_SIGN_ERROR;
    if (err == MZ_OK)
        result = PKCS12_parse(p12, cert_pwd, &evp_pkey, &cert, &ca_stack);
    if (result)
    {
        cms = CMS_sign(NULL, NULL, ca_stack, NULL, CMS_BINARY | CMS_PARTIAL);
        if (cms)
            signer_info = CMS_add1_signer(cms, cert, evp_pkey, EVP_sha256(), 0);
        if (signer_info == NULL)
        {
            err = MZ_SIGN_ERROR;
        }
        else
        {
            message_bio = BIO_new_mem_buf(message, message_size);
            signature_bio = BIO_new(BIO_s_mem());

            result = CMS_final(cms, message_bio, NULL, CMS_BINARY);
            if (result)
                result = i2d_CMS_bio(signature_bio, cms);
            if (result)
            {
                BIO_flush(signature_bio);
                BIO_get_mem_ptr(signature_bio, &buf_mem);

                *signature_size = buf_mem->length;
                *signature = MZ_ALLOC(buf_mem->length);
                
                memcpy(*signature, buf_mem->data, buf_mem->length);
            }
#if 0            
            BIO *yy = BIO_new_file("xyz", "wb");
            BIO_write(yy, *signature, *signature_size);
            BIO_flush(yy);
            BIO_free(yy);
#endif
        }
    }

    if (!result)
        err = MZ_SIGN_ERROR;

    if (cms)
        CMS_ContentInfo_free(cms);
    if (signature_bio)
        BIO_free(signature_bio);
    if (cert_bio)
        BIO_free(cert_bio);
    if (message_bio)
        BIO_free(message_bio);
    if (p12)
        PKCS12_free(p12);

    if (err != MZ_OK && *signature != NULL)
    {
        MZ_FREE(*signature);
        *signature = NULL;
        *signature_size = 0;
    }

    return err;
}
示例#4
0
文件: signature.c 项目: ukleinek/rauc
GBytes *cms_sign(GBytes *content, const gchar *certfile, const gchar *keyfile, gchar **interfiles, GError **error)
{
	GError *ierror = NULL;
	BIO *incontent = BIO_new_mem_buf((void *)g_bytes_get_data(content, NULL),
			g_bytes_get_size(content));
	BIO *outsig = BIO_new(BIO_s_mem());
	X509 *signcert = NULL;
	EVP_PKEY *pkey = NULL;
	STACK_OF(X509) *intercerts = NULL;
	CMS_ContentInfo *cms = NULL;
	GBytes *res = NULL;
	int flags = CMS_DETACHED | CMS_BINARY;

	g_return_val_if_fail(content != NULL, NULL);
	g_return_val_if_fail(certfile != NULL, NULL);
	g_return_val_if_fail(keyfile != NULL, NULL);
	g_return_val_if_fail(error == NULL || *error == NULL, NULL);

	signcert = load_cert(certfile, &ierror);
	if (signcert == NULL) {
		g_propagate_error(error, ierror);
		goto out;
	}

	pkey = load_key(keyfile, &ierror);
	if (pkey == NULL) {
		g_propagate_error(error, ierror);
		goto out;
	}

	intercerts = sk_X509_new_null();

	for (gchar **intercertpath = interfiles; intercertpath && *intercertpath != NULL; intercertpath++) {

		X509 *intercert = load_cert(*intercertpath, &ierror);
		if (intercert == NULL) {
			g_propagate_error(error, ierror);
			goto out;
		}

		sk_X509_push(intercerts, intercert);
	}

	cms = CMS_sign(signcert, pkey, intercerts, incontent, flags);
	if (cms == NULL) {
		unsigned long err;
		const gchar *data;
		int errflags;
		err = ERR_get_error_line_data(NULL, NULL, &data, &errflags);
		g_set_error(
				error,
				R_SIGNATURE_ERROR,
				R_SIGNATURE_ERROR_INVALID,
				"failed to create signature: %s", (errflags & ERR_TXT_STRING) ? data : ERR_error_string(err, NULL));
		goto out;
	}
	if (!i2d_CMS_bio(outsig, cms)) {
		g_set_error_literal(
				error,
				R_SIGNATURE_ERROR,
				R_SIGNATURE_ERROR_SERIALIZE_SIG,
				"failed to serialize signature");
		goto out;
	}

	res = bytes_from_bio(outsig);

	if (!res) {
		g_set_error_literal(
				error,
				R_SIGNATURE_ERROR,
				R_SIGNATURE_ERROR_UNKNOWN,
				"Read zero bytes");
		goto out;
	}

	/* keyring was given, perform verification to obtain trust chain */
	if (r_context()->config->keyring_path) {
		g_autoptr(CMS_ContentInfo) vcms = NULL;
		g_autoptr(X509_STORE) store = NULL;
		STACK_OF(X509) *verified_chain = NULL;

		g_message("Keyring given, doing signature verification");
		if (!cms_verify(content, res, &vcms, &store, &ierror)) {
			g_propagate_error(error, ierror);
			res = NULL;
			goto out;
		}

		if (!cms_get_cert_chain(vcms, store, &verified_chain, &ierror)) {
			g_propagate_error(error, ierror);
			res = NULL;
			goto out;
		}

		for (int i = 0; i < sk_X509_num(verified_chain); i++) {
			const ASN1_TIME *expiry_time;
			struct tm *next_month;
			time_t now;
			time_t comp;
			time(&now);

			next_month = gmtime(&now);
			next_month->tm_mon += 1;
			if (next_month->tm_mon == 12)
				next_month->tm_mon = 0;
			comp = timegm(next_month);

			expiry_time = X509_get0_notAfter(sk_X509_value(verified_chain, i));

			/* Check if expiry time is within last month */
			if (X509_cmp_current_time(expiry_time) == 1 && X509_cmp_time(expiry_time, &comp) == -1) {
				char buf[BUFSIZ];
				X509_NAME_oneline(X509_get_subject_name(sk_X509_value(verified_chain, i)),
						buf, sizeof buf);
				g_warning("Certificate %d (%s) will exipre in less than a month!", i + 1, buf);
			}
		}

		sk_X509_pop_free(verified_chain, X509_free);
	} else {
		g_message("No keyring given, skipping signature verification");
	}
out:
	ERR_print_errors_fp(stdout);
	BIO_free_all(incontent);
	BIO_free_all(outsig);
	return res;
}