bool asignify_pubkey_check_signature(struct asignify_public_data *pk, struct asignify_public_data *sig, const unsigned char *data, size_t dlen) { SHA2_CTX sh; unsigned char h[crypto_sign_HASHBYTES]; if (pk == NULL || sig == NULL) { return (false); } /* Check sanity */ if (pk->version != sig->version || pk->id_len != sig->id_len || (pk->id_len > 0 && memcmp(pk->id, sig->id, sig->id_len) != 0)) { return (false); } if (pk->version == sig->version) { switch (pk->version) { case 0: if (pk->data_len == crypto_sign_PUBLICKEYBYTES && sig->data_len == crypto_sign_BYTES) { SHA512Init(&sh); SHA512Update(&sh, sig->data, 32); SHA512Update(&sh, pk->data, 32); SHA512Update(&sh, data, dlen); SHA512Final(h, &sh); if (crypto_sign_ed25519_verify_detached(sig->data, h, pk->data) == 0) { return (true); } } break; case 1: if (pk->data_len == crypto_sign_PUBLICKEYBYTES && sig->data_len == crypto_sign_BYTES) { /* ED25519 */ SHA512Init(&sh); SHA512Update(&sh, sig->data, 32); SHA512Update(&sh, pk->data, 32); SHA512Update(&sh, (const uint8_t *)&sig->version, sizeof(sig->version)); SHA512Update(&sh, data, dlen); SHA512Final(h, &sh); if (crypto_sign_ed25519_verify_detached(sig->data, h, pk->data) == 0) { return (true); } } break; default: break; } } return (false); }
int crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) { return crypto_sign_ed25519_verify_detached(sig, m, mlen, pk); }
int verify_file(char *public_key_name, char *test_file_name) { int error = 0; char signature_magic[sizeof(SIGNATURE_MAGIC_STRING)]; unsigned char signature[crypto_hash_sha512_BYTES]; unsigned char public_key[crypto_sign_ed25519_PUBLICKEYBYTES]; size_t read; size_t test_file_size; size_t signature_field_size = crypto_sign_ed25519_BYTES + sizeof(SIGNATURE_MAGIC_STRING); FILE *public_key_file = NULL; FILE *test_file = NULL; unsigned char *test_file_contents = NULL; public_key_file = fopen(public_key_name, "r"); if (public_key_file == NULL) { perror("opening public key file"); error = -1; goto out; } test_file = fopen(test_file_name, "r"); if (test_file == NULL) { perror("opening test file"); error = -1; goto out; } error = get_file_size(test_file, &test_file_size); if (error != 0) { perror("Reading test file size"); goto out; } else if (test_file_size < crypto_sign_ed25519_PUBLICKEYBYTES) { fprintf(stderr, "File is too small to contain a signature\n"); error = -1; goto out; } read = fread(public_key, 1, sizeof(public_key), public_key_file); if (read != 1 || ferror(public_key_file) != 0) { perror("Reading public key"); error = -1; goto out; } test_file_contents = malloc(test_file_size); if (test_file_contents == NULL) { fprintf(stderr, "Couldn't allocate memory for test file contents\n"); error = -1; goto out; } read = fread(test_file_contents, test_file_size - signature_field_size, 1, test_file); if (read != 1 || ferror(test_file) != 0) { perror("Reading data from test file"); error = -1; goto out; } read = fread(signature_magic, sizeof(signature_magic), 1, test_file); if (read != 1 || ferror(test_file) != 0) { perror("Reading signature from test file"); error = -1; goto out; } if (strncmp(SIGNATURE_MAGIC_STRING, signature_magic, sizeof(SIGNATURE_MAGIC_STRING)) != 0) { fprintf(stderr, "Bad signature magic\n"); error = -1; goto out; } read = fread(signature, sizeof(signature), 1, test_file); if (read != 1 || ferror(test_file) != 0) { perror("Reading signature from test file"); error = -1; goto out; } read = ftell(test_file); if (read != test_file_size) { fprintf(stderr, "Bug reading signature\n"); error = -1; goto out; } #if DEBUG printf("Public key:\n"); print_bytes(public_key, sizeof(public_key)); printf("Signature:\n"); print_bytes(signature, sizeof(signature)); #endif error = crypto_sign_ed25519_verify_detached(signature, test_file_contents, test_file_size - sizeof(signature) - sizeof(signature_magic), public_key); if (error != 0) { fprintf(stderr, "Failed to verify file %s\n", test_file_name); goto out; } else { printf("Signature successfully verified\n"); } out: free(test_file_contents); fclose(public_key_file); fclose(test_file); return error; }