/* * Copyright (c) 2015, NORDUnet A/S. * See LICENSE for licensing information. */ #include #include #include #include #include "hsmhelper.h" #include "erlport.h" static long parseslot(char *slotstring) { char *endptr = NULL; if (slotstring[0] == '\0') { errx(1, "no slot given"); } long slot = strtol(slotstring, &endptr, 10); if (endptr[0] != '\0') { errx(1, "not a valid slot number: %s", slotstring); } return slot; } static void loop(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_MECHANISM_TYPE mechanism) { unsigned char buf[10000]; unsigned char signature[2048]; ssize_t len; while ((len = read_command(buf, sizeof(buf), 4)) > 0) { unsigned long signatureLen = sizeof(signature); sign(hSession, hKey, buf, len, signature, &signatureLen, mechanism); write_reply(signature, signatureLen, 4); } } #define MAX_PIN_SIZE 1000 char * read_pin(char *filename) { FILE *pin_file; char *result; pin_file = fopen(filename, "r"); if (pin_file == NULL) { return NULL; } char *pin = malloc(MAX_PIN_SIZE); result = fgets(pin, MAX_PIN_SIZE, pin_file); if (result == NULL) { free(pin); fclose(pin_file); return NULL; } size_t newlinepos = strcspn(result, "\r\n"); pin[newlinepos] = '\0'; fclose(pin_file); return pin; } int main(int argc, char *argv[]) { if (argc < 6) { errx(1, "usage: %s rsa|ecdsa ", argv[0]); } char *library_path = argv[1]; char *slotstring = argv[2]; char *keytype = argv[3]; char *keyname = argv[4]; char *pin_or_file = argv[5]; char *pin; if (pin_or_file[0] == '@') { pin = read_pin(pin_or_file + 1); } else { pin = strdup(pin_or_file); } if (pin == NULL) { errx(1, "Could not read pin"); } init(library_path); long slot = parseslot(slotstring); CK_MECHANISM_TYPE mechanism; if (strcmp(keytype, "ecdsa") == 0) { mechanism = CKM_ECDSA; } else if (strcmp(keytype, "rsa") == 0) { mechanism = CKM_SHA256_RSA_PKCS; } else { errx(1, "invalid key type: %s", keytype); } CK_SESSION_HANDLE hSession = open_session(slot); login(hSession, pin); CK_OBJECT_HANDLE hKey = find_key(hSession, CKO_PRIVATE_KEY, keyname); loop(hSession, hKey, mechanism); free(pin); return 0; }