commit 2cfcda3e0c4556a11918997d81d6ead71adc7aa4
parent 8fd4617d0ee6399ca30e97bc1a73244c87137af4
Author: lash <dev@holbrook.no>
Date: Wed, 24 Apr 2024 08:46:44 +0100
Complete sign/verify test for ledger and ledger item
Diffstat:
4 files changed, 193 insertions(+), 22 deletions(-)
diff --git a/src/gpg.c b/src/gpg.c
@@ -14,6 +14,7 @@
const char *gpgVersion = NULL;
+const char sign_test[64];
size_t get_padsize(size_t insize, size_t blocksize) {
@@ -275,7 +276,7 @@ static int key_create_file(gcry_sexp_t *key, const char *p, const char *passphra
int gpg_key_create(gcry_sexp_t *key) {
- const char *sexp_quick = "(genkey(ecc(curve Ed25519)))";
+ const char *sexp_quick = "(genkey(ecc(flags eddsa)(curve Ed25519)))";
//char *pv;
gcry_sexp_t in;
gcry_error_t e;
@@ -293,22 +294,48 @@ int gpg_key_create(gcry_sexp_t *key) {
return 0;
}
-static int sign(gcry_sexp_t *out, gcry_sexp_t *key, const char *v) {
+int gpg_sign(gcry_sexp_t *out, gcry_sexp_t *key, const char *v) {
gcry_error_t e;
gcry_sexp_t data;
+ size_t err_offset;
char in[BUFLEN];
- sprintf(in, "(data(flags eddsa(hash-algo sha512(value %s))))", v);
- gcry_sexp_new(&data, in, strlen(in), 0);
+ e = gcry_sexp_build(&data, &err_offset, "(data(flags eddsa)(hash-algo sha512)(value %b))", 64, v);
+ if (e) {
+ sprintf(in, "error sign sexp data build: %s\n", gcry_strerror(e));
+ debug_log(DEBUG_ERROR, in);
+ return ERR_KEYFAIL;
+ }
e = gcry_pk_sign(out, data, *key);
if (e) {
sprintf(in, "error sign: %s\n", gcry_strerror(e));
debug_log(DEBUG_ERROR, in);
return ERR_KEYFAIL;
}
+
return 0;
}
+int gpg_verify(gcry_sexp_t *sig, gcry_sexp_t *key, const char *v) {
+ gcry_error_t e;
+ gcry_sexp_t data;
+ size_t err_offset;
+ char in[BUFLEN];
+
+ e = gcry_sexp_build(&data, &err_offset, "(data(flags eddsa)(hash-algo sha512)(value %b))", 64, v);
+ if (e) {
+ sprintf(in, "error sign sexp data build: %s\n", gcry_strerror(e));
+ debug_log(DEBUG_ERROR, in);
+ return ERR_KEYFAIL;
+ }
+ e = gcry_pk_verify(*sig, data, *key);
+ if (e != GPG_ERR_NO_ERROR) {
+ sprintf(in, "error verify: %s\n", gcry_strerror(e));
+ debug_log(DEBUG_ERROR, in);
+ return 1;
+ }
+}
+
char *gpg_store_get_fingerprint(struct gpg_store *gpg) {
return gpg->fingerprint;
}
@@ -392,6 +419,6 @@ int gpg_store_check(struct gpg_store *gpg, const char *passphrase) {
sprintf(pp, "found key %s in %s", (unsigned char*)gpg->fingerprint, p);
debug_log(DEBUG_INFO, pp);
}
- r = sign(&o, &k, "foo");
+ r = gpg_sign(&o, &k, sign_test);
return r;
}
diff --git a/src/gpg.h b/src/gpg.h
@@ -88,5 +88,6 @@ int gpg_store_check(struct gpg_store *gpg, const char *passphrase);
int gpg_store_digest(struct gpg_store *gpg, char *out, const char *in);
char *gpg_store_get_fingerprint(struct gpg_store *gpg);
int gpg_key_create(gcry_sexp_t *key);
+int gpg_sign(gcry_sexp_t *out, gcry_sexp_t *key, const char *v);
#endif
diff --git a/src/ledger.c b/src/ledger.c
@@ -78,13 +78,13 @@ static char *get_message(asn1_node item, char *out_digest, char *out_data, size_
printf("%d (%s) %s\n", r, err, asn1_strerror(r));
return NULL;
}
-
- c = 64;
- r = asn1_read_value(item, "signatureResponse", sig, (int*)&c);
- if (r != ASN1_SUCCESS) {
- printf("%d (%s) %s\n", r, err, asn1_strerror(r));
- return NULL;
- }
+//
+// c = 64;
+// r = asn1_read_value(item, "signatureResponse", sig, (int*)&c);
+// if (r != ASN1_SUCCESS) {
+// printf("%d (%s) %s\n", r, err, asn1_strerror(r));
+// return NULL;
+// }
buf[0] = 0;
c = 0;
diff --git a/src/tests/sign.c b/src/tests/sign.c
@@ -6,24 +6,39 @@
const char *content_test = "Subject: foo\n\nsome content\n";
const char *content_test_item = "Subject: bar\n\nsome other content\n";
-const char *content_test_item_two = "Subject: baz\n\nmore more more content\n";
int main() {
int r;
+ size_t c;
gcry_sexp_t alice;
+ gcry_sexp_t alice_pub;
gcry_sexp_t bob;
+ gcry_sexp_t bob_pub;
gcry_sexp_t tmp;
+ gcry_sexp_t sig;
+ gcry_sexp_t msg;
+ gcry_mpi_t sr;
+ gcry_mpi_t ss;
+ gcry_error_t err;
+ char *p;
char *out;
size_t out_len;
char *out_item;
size_t out_item_len;
struct kee_ledger_t ledger;
struct kee_ledger_item_t item;
- struct kee_ledger_item_t item_two;
+ struct kee_ledger_item_t *item_parsed;
struct kee_content_t content;
struct kee_content_t content_item;
- struct kee_content_t content_item_two;
char item_sum[64];
+ const char *version;
+
+ version = gcry_check_version(NULL);
+ if (version == 0x0) {
+ return 1;
+ }
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
r = gpg_key_create(&alice);
if (r) {
@@ -83,7 +98,7 @@ int main() {
return 1;
}
- out_len = 4096;
+ out_len = 1024*1024;
out = malloc(out_len);
r = kee_ledger_serialize(&ledger, out, &out_len);
if (r) {
@@ -116,22 +131,150 @@ int main() {
return 1;
}
- free(out);
- kee_content_free(&content_item);
- kee_content_free(&content);
- kee_ledger_free(&ledger);
-
out_item_len = 4096;
- out_item = malloc(out_len);
+ out_item = malloc(out_item_len);
r = kee_ledger_item_serialize(&item, out_item, &out_item_len, KEE_LEDGER_ITEM_SERIALIZE_REQUEST);
if (r) {
return 1;
}
+ r = calculate_digest_algo(out_item, out_item_len, item_sum, GCRY_MD_SHA512);
+ if (r) {
+ return 1;
+ }
+ r = gpg_sign(&sig, &bob, item_sum);
+ if (r) {
+ return 1;
+ }
+ c = 0;
+ bob_pub = gcry_sexp_find_token(bob, "public-key", 10);
+ if (bob_pub == NULL) {
+ return 1;
+ }
+ err = gcry_sexp_build(&bob_pub, &c, "(key-data%S)", bob_pub);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ r = gpg_verify(&sig, &bob, item_sum);
+ if (r) {
+ return 1;
+ }
+ tmp = gcry_sexp_find_token(sig, "r", 1);
+ if (tmp == NULL) {
+ return 1;
+ }
+ sr = gcry_sexp_nth_mpi(tmp, 1, GCRYMPI_FMT_STD);
+ if (sr == NULL) {
+ return 1;
+ }
+ tmp = gcry_sexp_find_token(sig, "s", 1);
+ if (tmp == NULL) {
+ return 1;
+ }
+ ss = gcry_sexp_nth_mpi(tmp, 1, GCRYMPI_FMT_STD);
+ if (ss == NULL) {
+ return 1;
+ }
+ c = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_STD, item_sum, 32, &c, sr);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ if (c != 32) {
+ return 1;
+ }
+ memcpy(item.bob_signature, item_sum, 32);
+ c = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_STD, item_sum, 32, &c, ss);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ if (c != 32) {
+ return 1;
+ }
+ memcpy(item.bob_signature+32, item_sum, 32);
+
+ out_item_len = 4096;
+ r = kee_ledger_item_serialize(&item, out_item, &out_item_len, KEE_LEDGER_ITEM_SERIALIZE_RESPONSE);
+ if (r) {
+ return 1;
+ }
r = calculate_digest_algo(out_item, out_item_len, item_sum, GCRY_MD_SHA512);
if (r) {
return 1;
}
+ r = gpg_sign(&sig, &alice, item_sum);
+ if (r) {
+ return 1;
+ }
+ c = 0;
+ alice_pub = gcry_sexp_find_token(alice, "public-key", 10);
+ if (alice_pub == NULL) {
+ return 1;
+ }
+ err = gcry_sexp_build(&alice_pub, &c, "(key-data%S)", alice_pub);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ r = gpg_verify(&sig, &alice, item_sum);
+ if (r) {
+ return 1;
+ }
+ tmp = NULL;
+ tmp = gcry_sexp_find_token(sig, "r", 1);
+ if (tmp == NULL) {
+ return 1;
+ }
+ sr = gcry_sexp_nth_mpi(tmp, 1, GCRYMPI_FMT_STD);
+ if (sr == NULL) {
+ return 1;
+ }
+ tmp = NULL;
+ tmp = gcry_sexp_find_token(sig, "s", 1);
+ if (tmp == NULL) {
+ return 1;
+ }
+ ss = gcry_sexp_nth_mpi(tmp, 1, GCRYMPI_FMT_STD);
+ if (ss == NULL) {
+ return 1;
+ }
+ c = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_STD, item_sum, 32, &c, sr);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ if (c != 32) {
+ return 1;
+ }
+ memcpy(item.alice_signature, item_sum, 32);
+ c = 0;
+ err = gcry_mpi_print(GCRYMPI_FMT_STD, item_sum, 32, &c, ss);
+ if (err != GPG_ERR_NO_ERROR) {
+ return 1;
+ }
+ if (c != 32) {
+ return 1;
+ }
+ memcpy(item.alice_signature+32, item_sum, 32);
+
+ out_item_len = 4096;
+ r = kee_ledger_item_serialize(&item, out_item, &out_item_len, KEE_LEDGER_ITEM_SERIALIZE_FINAL);
+ if (r) {
+ return 1;
+ }
+ *(out_item+out_item_len) = 1;
+
+ item_parsed = kee_ledger_parse_item(&ledger, out_item, out_item_len + 1);
+ if (item_parsed == NULL) {
+ return 1;
+ }
+ tmp = NULL;
+
+ free(out_item);
+ free(out);
+ kee_content_free(&content_item);
+ kee_content_free(&content);
+ kee_ledger_free(&ledger);
return 0;
}