129 lines
2.8 KiB
C
129 lines
2.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <err.h>
|
|
#include <arpa/inet.h>
|
|
#include <openssl/bio.h>
|
|
#include <openssl/evp.h>
|
|
#include <openssl/pem.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/engine.h>
|
|
#include <openssl/conf.h>
|
|
|
|
static void display_openssl_errors(int l)
|
|
{
|
|
const char *file;
|
|
char buf[120];
|
|
int e, line;
|
|
|
|
if (ERR_peek_error() == 0)
|
|
return;
|
|
fprintf(stderr, "At %s:%d:\n", __FILE__, l);
|
|
|
|
while ((e = ERR_get_error_line(&file, &line))) {
|
|
ERR_error_string(e, buf);
|
|
fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
|
|
}
|
|
}
|
|
|
|
/* This program accepts on the command line:
|
|
* 1. A PKCS#11 URL specifying a private key
|
|
* 2. A PIN
|
|
* 3. A PKCS#11 shared module (optional)
|
|
*
|
|
* And signs test data with the provided key.
|
|
*
|
|
* Example: ./a.out "pkcs11:object=myobject" 1234 /usr/lib64/pkcs11/opensc-pkcs11.so
|
|
*/
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *private_key_name;
|
|
unsigned char buf[4096];
|
|
const EVP_MD *digest_algo;
|
|
EVP_PKEY *private_key;
|
|
char *key_pass = NULL;
|
|
unsigned n;
|
|
ENGINE *e;
|
|
EVP_MD_CTX ctx;
|
|
const char *module_path = NULL;
|
|
|
|
if (argc < 2) {
|
|
fprintf(stderr, "usage: %s [private key URL] [PIN] [module]\n", argv[0]);
|
|
fprintf(stderr, "\n");
|
|
exit(1);
|
|
}
|
|
|
|
private_key_name = argv[1];
|
|
key_pass = argv[2];
|
|
if (argc >= 3)
|
|
module_path = argv[3];
|
|
|
|
//+ Features HSM-OpenSSL
|
|
OpenSSL_add_all_algorithms();
|
|
ERR_load_crypto_strings();
|
|
ERR_clear_error();
|
|
ENGINE_load_builtin_engines();
|
|
|
|
e = ENGINE_by_id("pkcs11");
|
|
if (!e) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
if (module_path) {
|
|
fprintf(stderr, "loading: %s\n", module_path);
|
|
if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", module_path, 0)) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
if (!ENGINE_init(e)) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
if (key_pass && !ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
|
|
if (!private_key) {
|
|
fprintf(stderr, "cannot load: %s\n", private_key_name);
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
display_openssl_errors(__LINE__);
|
|
|
|
digest_algo = EVP_get_digestbyname("sha256");
|
|
|
|
EVP_MD_CTX_init(&ctx);
|
|
if (EVP_DigestInit(&ctx, digest_algo) <= 0) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
EVP_SignInit(&ctx, digest_algo);
|
|
|
|
#define TEST_DATA "test data"
|
|
if (EVP_SignUpdate(&ctx, TEST_DATA, sizeof(TEST_DATA) - 1) <= 0) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
n = sizeof(buf);
|
|
if (EVP_SignFinal(&ctx, buf, &n, private_key) <= 0) {
|
|
display_openssl_errors(__LINE__);
|
|
exit(1);
|
|
}
|
|
|
|
EVP_PKEY_free(private_key);
|
|
ENGINE_finish(e);
|
|
//-
|
|
|
|
return 0;
|
|
}
|