diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-21 12:46:12 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-21 12:46:12 +0000 |
commit | 2d5ce53dfad6d68a4f7972d10bce5a08c7e8a7a9 (patch) | |
tree | b86ef65e7298e8080da653e5cc45c935524568bd /src | |
parent | f4b58f2af06eef67db1be061a59adf6e9cd2fc63 (diff) | |
download | gnunet-2d5ce53dfad6d68a4f7972d10bce5a08c7e8a7a9.tar.gz gnunet-2d5ce53dfad6d68a4f7972d10bce5a08c7e8a7a9.zip |
-updating pseudonym crypto implementation
Diffstat (limited to 'src')
-rw-r--r-- | src/util/pseudonym.c | 278 |
1 files changed, 225 insertions, 53 deletions
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c index 994373052..428e81943 100644 --- a/src/util/pseudonym.c +++ b/src/util/pseudonym.c | |||
@@ -871,8 +871,12 @@ GNUNET_PSEUDONYM_create (const char *filename) | |||
871 | ssize_t ret; | 871 | ssize_t ret; |
872 | gcry_sexp_t r_key; | 872 | gcry_sexp_t r_key; |
873 | gcry_sexp_t params; | 873 | gcry_sexp_t params; |
874 | gcry_ctx_t ctx; | ||
875 | gcry_mpi_point_t q; | ||
876 | gcry_mpi_t q_x; | ||
877 | gcry_mpi_t q_y; | ||
874 | gcry_error_t rc; | 878 | gcry_error_t rc; |
875 | gcry_mpi_t skey[2]; | 879 | gcry_mpi_t d; |
876 | size_t size; | 880 | size_t size; |
877 | 881 | ||
878 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); | 882 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); |
@@ -893,28 +897,71 @@ GNUNET_PSEUDONYM_create (const char *filename) | |||
893 | } | 897 | } |
894 | if (0 != (rc = gcry_pk_genkey (&r_key, params))) | 898 | if (0 != (rc = gcry_pk_genkey (&r_key, params))) |
895 | { | 899 | { |
896 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 900 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc); |
901 | gcry_sexp_release (r_key); | ||
897 | return NULL; | 902 | return NULL; |
898 | } | 903 | } |
899 | /* NOTE: treating a point as a normal MPI value; hopefully that works... */ | 904 | /* extract "d" (secret key) from r_key */ |
900 | rc = key_from_sexp (skey, r_key, "private-key", "dq"); | 905 | rc = key_from_sexp (&d, r_key, "private-key", "d"); |
901 | if (0 != rc) | 906 | if (0 != rc) |
902 | rc = key_from_sexp (skey, r_key, "private-key", "dq"); | 907 | rc = key_from_sexp (&d, r_key, "private-key", "d"); |
903 | if (0 != rc) | 908 | if (0 != rc) |
904 | rc = key_from_sexp (skey, r_key, "ecc", "dq"); | 909 | rc = key_from_sexp (&d, r_key, "ecc", "d"); |
905 | gcry_sexp_release (r_key); | 910 | if (0 != rc) |
911 | { | ||
912 | gcry_sexp_release (r_key); | ||
913 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc); | ||
914 | return NULL; | ||
915 | } | ||
906 | size = sizeof (ph->d); | 916 | size = sizeof (ph->d); |
907 | GNUNET_assert (0 == | 917 | GNUNET_assert (0 == |
908 | gcry_mpi_print (GCRYMPI_FMT_USG, ph->d, size, &size, | 918 | gcry_mpi_print (GCRYMPI_FMT_USG, ph->d, size, &size, |
909 | skey[0])); | 919 | d)); |
920 | gcry_mpi_release (d); | ||
910 | adjust (ph->d, size, sizeof (ph->d)); | 921 | adjust (ph->d, size, sizeof (ph->d)); |
911 | size = sizeof (ph->public_key.q); | 922 | |
912 | GNUNET_assert (0 == | 923 | /* extract 'q' (public key) from r_key */ |
913 | gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q, size, &size, | 924 | if (0 != (rc = gcry_mpi_ec_new (&ctx, r_key, NULL))) |
914 | skey[1])); | 925 | { |
915 | adjust (ph->public_key.q, size, sizeof (ph->public_key.q)); | 926 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ |
916 | gcry_mpi_release (skey[0]); | 927 | gcry_sexp_release (r_key); |
917 | gcry_mpi_release (skey[1]); | 928 | return NULL; |
929 | } | ||
930 | gcry_sexp_release (r_key); | ||
931 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | ||
932 | q_x = gcry_mpi_new (256); | ||
933 | q_y = gcry_mpi_new (256); | ||
934 | gcry_mpi_ec_get_affine (q_x, q_y, q, ctx); | ||
935 | gcry_mpi_point_release (q); | ||
936 | |||
937 | /* store q_x/q_y in public key */ | ||
938 | size = sizeof (ph->public_key.q_x); | ||
939 | if (0 != | ||
940 | gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_x, size, &size, | ||
941 | q_x)) | ||
942 | { | ||
943 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
944 | gcry_mpi_release (q_x); | ||
945 | gcry_mpi_release (q_y); | ||
946 | return NULL; | ||
947 | |||
948 | } | ||
949 | adjust (ph->public_key.q_x, size, sizeof (ph->public_key.q_x)); | ||
950 | gcry_mpi_release (q_x); | ||
951 | |||
952 | size = sizeof (ph->public_key.q_y); | ||
953 | if (0 != | ||
954 | gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_y, size, &size, | ||
955 | q_y)) | ||
956 | { | ||
957 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
958 | gcry_mpi_release (q_y); | ||
959 | return NULL; | ||
960 | } | ||
961 | adjust (ph->public_key.q_y, size, sizeof (ph->public_key.q_y)); | ||
962 | gcry_mpi_release (q_y); | ||
963 | |||
964 | /* write to disk */ | ||
918 | if (NULL != filename) | 965 | if (NULL != filename) |
919 | { | 966 | { |
920 | ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_PseudonymHandle), | 967 | ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_PseudonymHandle), |
@@ -968,14 +1015,11 @@ GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle () | |||
968 | struct GNUNET_PseudonymHandle *ph; | 1015 | struct GNUNET_PseudonymHandle *ph; |
969 | 1016 | ||
970 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); | 1017 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); |
971 | /* FIXME: if we use 'd=0' for the anonymous handle (as per#2564), | 1018 | /* Note if we use 'd=0' for the anonymous handle (as per#2564), |
972 | then I believe the public key should be also zero, as Q=0P=0. | 1019 | then I believe the public key should be also zero, as Q=0P=0; |
973 | However, libgcrypt's point representation is completely internal, | 1020 | so setting everything to all-zeros (as per GNUNET_malloc) |
974 | and treats a z-coordinate of zero as infinity, so we likely need | 1021 | should be all that is needed here). |
975 | to set it to (0,0,1) internally --- or actually calculate Q=qP | ||
976 | explicitly. Either way, we don't have an API to do so yet :-(. | ||
977 | */ | 1022 | */ |
978 | GNUNET_break (0); | ||
979 | return ph; | 1023 | return ph; |
980 | } | 1024 | } |
981 | 1025 | ||
@@ -1097,8 +1141,7 @@ GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | |||
1097 | gcry_mpi_release (n); | 1141 | gcry_mpi_release (n); |
1098 | 1142 | ||
1099 | /* now build sexpression with the signing key; | 1143 | /* now build sexpression with the signing key; |
1100 | NOTE: libgcrypt docs say that we should specify 'Q', but | 1144 | NOTE: libgcrypt docs say that we should specify 'Q', but hopefully soon |
1101 | with the current API we cannot calculate Q=dP, so hopefully | ||
1102 | libgcrypt will derive it from 'd' for us... */ | 1145 | libgcrypt will derive it from 'd' for us... */ |
1103 | if (0 != (rc = gcry_sexp_build (&spriv, &erroff, | 1146 | if (0 != (rc = gcry_sexp_build (&spriv, &erroff, |
1104 | "(private-key(ecc(curve \"NIST P-256\")(d %m)))", | 1147 | "(private-key(ecc(curve \"NIST P-256\")(d %m)))", |
@@ -1145,10 +1188,8 @@ GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | |||
1145 | gcry_sexp_release (data); | 1188 | gcry_sexp_release (data); |
1146 | gcry_sexp_release (spriv); | 1189 | gcry_sexp_release (spriv); |
1147 | 1190 | ||
1148 | /* extract 'r' and 's' values from sexpression 'result' and store in 'signature'; | 1191 | /* extract 'r' and 's' values from sexpression 'result' and store in 'signature' */ |
1149 | FIXME: libgcrypt does not document format of s-expression returned for ECC | 1192 | if (0 != (rc = key_from_sexp (rs, result, "ecdsa", "rs"))) |
1150 | signatures; so "ecc" here is just a guess. */ | ||
1151 | if (0 != (rc = key_from_sexp (rs, result, "ecc", "rs"))) | ||
1152 | { | 1193 | { |
1153 | GNUNET_break (0); | 1194 | GNUNET_break (0); |
1154 | gcry_sexp_release (result); | 1195 | gcry_sexp_release (result); |
@@ -1156,7 +1197,7 @@ GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | |||
1156 | } | 1197 | } |
1157 | gcry_sexp_release (result); | 1198 | gcry_sexp_release (result); |
1158 | size = sizeof (signature->sig_r); | 1199 | size = sizeof (signature->sig_r); |
1159 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) signature->sig_r, size, | 1200 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_r, size, |
1160 | &size, rs[0]))) | 1201 | &size, rs[0]))) |
1161 | { | 1202 | { |
1162 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | 1203 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); |
@@ -1166,7 +1207,7 @@ GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | |||
1166 | } | 1207 | } |
1167 | gcry_mpi_release (rs[0]); | 1208 | gcry_mpi_release (rs[0]); |
1168 | size = sizeof (signature->sig_s); | 1209 | size = sizeof (signature->sig_s); |
1169 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) signature->sig_s, size, | 1210 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_s, size, |
1170 | &size, rs[1]))) | 1211 | &size, rs[1]))) |
1171 | { | 1212 | { |
1172 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | 1213 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); |
@@ -1179,6 +1220,60 @@ GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | |||
1179 | 1220 | ||
1180 | 1221 | ||
1181 | /** | 1222 | /** |
1223 | * Get an ECC context (with Q set to the respective public key) from | ||
1224 | * a pseudonym. | ||
1225 | * | ||
1226 | * @param pseudonym with information on 'q' | ||
1227 | * @return curve context | ||
1228 | */ | ||
1229 | static gcry_ctx_t | ||
1230 | get_context_from_pseudonym (struct GNUNET_PseudonymIdentifier *pseudonym) | ||
1231 | { | ||
1232 | gcry_ctx_t ctx; | ||
1233 | gcry_mpi_t ONE; | ||
1234 | gcry_mpi_t q_x; | ||
1235 | gcry_mpi_t q_y; | ||
1236 | gcry_mpi_point_t q; | ||
1237 | size_t size; | ||
1238 | int rc; | ||
1239 | |||
1240 | /* extract 'q' from pseudonym */ | ||
1241 | size = sizeof (pseudonym->q_x); | ||
1242 | if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, pseudonym->q_x, size, &size))) | ||
1243 | { | ||
1244 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1245 | return NULL; | ||
1246 | } | ||
1247 | size = sizeof (pseudonym->q_y); | ||
1248 | if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, pseudonym->q_y, size, &size))) | ||
1249 | { | ||
1250 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1251 | gcry_mpi_release (q_x); | ||
1252 | return NULL; | ||
1253 | } | ||
1254 | q = gcry_mpi_point_new (256); | ||
1255 | ONE = gcry_mpi_new (1); | ||
1256 | gcry_mpi_set_ui (ONE, 1); | ||
1257 | gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function 'set_affine'? */ | ||
1258 | gcry_mpi_release (ONE); | ||
1259 | gcry_mpi_release (q_x); | ||
1260 | gcry_mpi_release (q_y); | ||
1261 | |||
1262 | /* create basic ECC context */ | ||
1263 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) | ||
1264 | { | ||
1265 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
1266 | gcry_mpi_point_release (q); | ||
1267 | return NULL; | ||
1268 | } | ||
1269 | /* initialize 'ctx' with 'q' */ | ||
1270 | gcry_mpi_ec_set_point ("q", q, ctx); | ||
1271 | gcry_mpi_point_release (q); | ||
1272 | return ctx; | ||
1273 | } | ||
1274 | |||
1275 | |||
1276 | /** | ||
1182 | * Given a pseudonym and a signing key, derive the corresponding public | 1277 | * Given a pseudonym and a signing key, derive the corresponding public |
1183 | * key that would be used to verify the resulting signature. | 1278 | * key that would be used to verify the resulting signature. |
1184 | * | 1279 | * |
@@ -1194,11 +1289,16 @@ GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier *pse | |||
1194 | const struct GNUNET_HashCode *signing_key, | 1289 | const struct GNUNET_HashCode *signing_key, |
1195 | struct GNUNET_PseudonymIdentifier *verification_key) | 1290 | struct GNUNET_PseudonymIdentifier *verification_key) |
1196 | { | 1291 | { |
1197 | struct GNUNET_HashCode hc; | ||
1198 | struct GNUNET_HashCode x; | ||
1199 | gcry_mpi_t h; | 1292 | gcry_mpi_t h; |
1200 | size_t size; | 1293 | size_t size; |
1201 | int rc; | 1294 | int rc; |
1295 | gcry_ctx_t ctx; | ||
1296 | gcry_mpi_point_t g; | ||
1297 | gcry_mpi_point_t q; | ||
1298 | gcry_mpi_point_t hg; | ||
1299 | gcry_mpi_point_t v; | ||
1300 | gcry_mpi_t v_x; | ||
1301 | gcry_mpi_t v_y; | ||
1202 | 1302 | ||
1203 | /* get 'h' value from signing key */ | 1303 | /* get 'h' value from signing key */ |
1204 | size = sizeof (struct GNUNET_HashCode); | 1304 | size = sizeof (struct GNUNET_HashCode); |
@@ -1209,15 +1309,53 @@ GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier *pse | |||
1209 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 1309 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
1210 | return GNUNET_SYSERR; | 1310 | return GNUNET_SYSERR; |
1211 | } | 1311 | } |
1212 | /* FIXME: calculate hQ --- need point multiplication API! */ | 1312 | /* create ECC context based on Q from pseudonym */ |
1313 | if (NULL == (ctx = get_context_from_pseudonym (pseudonym))) | ||
1314 | { | ||
1315 | gcry_mpi_release (h); | ||
1316 | return GNUNET_SYSERR; | ||
1317 | } | ||
1318 | /* get G */ | ||
1319 | g = gcry_mpi_ec_get_point ("g", ctx, 0); | ||
1320 | |||
1321 | /* then call the 'multiply' function, to compute the product hG */ | ||
1322 | hg = gcry_mpi_point_new (0); | ||
1323 | gcry_mpi_ec_mul (hg, h, g, ctx); | ||
1213 | gcry_mpi_release (h); | 1324 | gcry_mpi_release (h); |
1214 | /* FIXME: calculate V = dQ + hQ --- need point addition API! */ | 1325 | |
1326 | /* get Q = dG from 'pseudonym' */ | ||
1327 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | ||
1328 | |||
1329 | /* calculate V = q + hG = dG + hG */ | ||
1330 | v = gcry_mpi_point_new (0); | ||
1331 | gcry_mpi_ec_add (v, q, hg, ctx); | ||
1215 | 1332 | ||
1216 | GNUNET_break (0); | 1333 | /* store 'v' point in "verification_key" */ |
1217 | GNUNET_CRYPTO_hash (pseudonym, sizeof (*pseudonym), &hc); | 1334 | v_x = gcry_mpi_new (256); |
1218 | GNUNET_CRYPTO_hash_xor (&hc, signing_key, &x); | 1335 | v_y = gcry_mpi_new (256); |
1219 | memset (verification_key, 0, sizeof (struct GNUNET_PseudonymIdentifier)); | 1336 | gcry_mpi_ec_get_affine (v_x, v_y, v, ctx); |
1220 | memcpy (verification_key, &x, GNUNET_MIN (sizeof (x), sizeof (*verification_key))); | 1337 | gcry_mpi_point_release (v); |
1338 | gcry_ctx_release (ctx); | ||
1339 | |||
1340 | size = sizeof (verification_key->q_x); | ||
1341 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_x, size, | ||
1342 | &size, v_x))) | ||
1343 | { | ||
1344 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
1345 | gcry_mpi_release (v_x); | ||
1346 | gcry_mpi_release (v_y); | ||
1347 | return GNUNET_SYSERR; | ||
1348 | } | ||
1349 | gcry_mpi_release (v_x); | ||
1350 | size = sizeof (verification_key->q_y); | ||
1351 | if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_y, size, | ||
1352 | &size, v_y))) | ||
1353 | { | ||
1354 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
1355 | gcry_mpi_release (v_y); | ||
1356 | return GNUNET_SYSERR; | ||
1357 | } | ||
1358 | gcry_mpi_release (v_y); | ||
1221 | return GNUNET_OK; | 1359 | return GNUNET_OK; |
1222 | } | 1360 | } |
1223 | 1361 | ||
@@ -1237,14 +1375,18 @@ GNUNET_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose *purpose, | |||
1237 | const struct GNUNET_PseudonymSignature *signature, | 1375 | const struct GNUNET_PseudonymSignature *signature, |
1238 | const struct GNUNET_PseudonymIdentifier *verification_key) | 1376 | const struct GNUNET_PseudonymIdentifier *verification_key) |
1239 | { | 1377 | { |
1240 | #if FUTURE | 1378 | #if FUTURE |
1241 | gcry_sexp_t data; | 1379 | gcry_sexp_t data; |
1242 | gcry_sexp_t sig_sexpr; | 1380 | gcry_sexp_t sig_sexpr; |
1243 | gcry_sexp_t pk_sexpr; | 1381 | gcry_sexp_t pk_sexpr; |
1244 | size_t size; | 1382 | size_t size; |
1383 | gcry_ctx_t ctx; | ||
1384 | gcry_mpi_t ONE; | ||
1245 | gcry_mpi_t r; | 1385 | gcry_mpi_t r; |
1246 | gcry_mpi_t s; | 1386 | gcry_mpi_t s; |
1247 | gcry_mpi_t q; | 1387 | gcry_mpi_point_t q; |
1388 | gcry_mpi_t q_x; | ||
1389 | gcry_mpi_t q_y; | ||
1248 | size_t erroff; | 1390 | size_t erroff; |
1249 | int rc; | 1391 | int rc; |
1250 | 1392 | ||
@@ -1264,7 +1406,7 @@ GNUNET_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose *purpose, | |||
1264 | gcry_mpi_release (r); | 1406 | gcry_mpi_release (r); |
1265 | return GNUNET_SYSERR; | 1407 | return GNUNET_SYSERR; |
1266 | } | 1408 | } |
1267 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecc(r %m)(s %m)))", | 1409 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecdsa(r %m)(s %m)))", |
1268 | r, s))) | 1410 | r, s))) |
1269 | { | 1411 | { |
1270 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 1412 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
@@ -1278,27 +1420,57 @@ GNUNET_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose *purpose, | |||
1278 | /* build s-expression for data that was signed */ | 1420 | /* build s-expression for data that was signed */ |
1279 | data = data_to_pkcs1 (purpose); | 1421 | data = data_to_pkcs1 (purpose); |
1280 | 1422 | ||
1281 | /* build s-expression for public key */ | 1423 | /* create context of public key and initialize Q */ |
1282 | /* NOTE: treating a point as a normal MPI value; hopefully that works... */ | 1424 | size = sizeof (verification_key->q_x); |
1283 | size = sizeof (verification_key->q); | 1425 | if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, |
1284 | if (0 != (rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG, | 1426 | verification_key->q_x, size, &size))) |
1285 | verification_key->q, size, &size))) | ||
1286 | { | 1427 | { |
1287 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 1428 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
1288 | gcry_sexp_release (data); | 1429 | gcry_sexp_release (data); |
1289 | gcry_sexp_release (sig_sexpr); | 1430 | gcry_sexp_release (sig_sexpr); |
1290 | return GNUNET_SYSERR; | 1431 | return GNUNET_SYSERR; |
1291 | } | 1432 | } |
1292 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(public-key(ecc(curve \"NIST P-256\")(q %m)))", | 1433 | size = sizeof (verification_key->q_y); |
1293 | q))) | 1434 | if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, |
1435 | verification_key->q_y, size, &size))) | ||
1294 | { | 1436 | { |
1295 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 1437 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
1296 | gcry_mpi_release (q); | 1438 | gcry_sexp_release (data); |
1439 | gcry_sexp_release (sig_sexpr); | ||
1440 | gcry_mpi_release (q_x); | ||
1441 | return GNUNET_SYSERR; | ||
1442 | } | ||
1443 | q = gcry_mpi_point_new (256); | ||
1444 | ONE = gcry_mpi_new (1); | ||
1445 | gcry_mpi_set_ui (ONE, 1); | ||
1446 | gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function 'set_affine'? */ | ||
1447 | gcry_mpi_release (ONE); | ||
1448 | gcry_mpi_release (q_x); | ||
1449 | gcry_mpi_release (q_y); | ||
1450 | |||
1451 | /* create basic ECC context */ | ||
1452 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) | ||
1453 | { | ||
1454 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
1455 | gcry_sexp_release (data); | ||
1456 | gcry_sexp_release (sig_sexpr); | ||
1457 | gcry_mpi_point_release (q); | ||
1458 | return GNUNET_SYSERR; | ||
1459 | } | ||
1460 | /* initialize 'ctx' with 'q' */ | ||
1461 | gcry_mpi_ec_set_point ("q", q, ctx); | ||
1462 | gcry_mpi_point_release (q); | ||
1463 | |||
1464 | /* convert 'ctx' to 'sexp' (this hurts) */ | ||
1465 | if (0 != (rc = gcry_sexp_from_context (&pk_sexpr, ctx))) | ||
1466 | { | ||
1467 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc); | ||
1468 | gcry_ctx_release (ctx); | ||
1297 | gcry_sexp_release (data); | 1469 | gcry_sexp_release (data); |
1298 | gcry_sexp_release (sig_sexpr); | 1470 | gcry_sexp_release (sig_sexpr); |
1299 | return GNUNET_SYSERR; | 1471 | return GNUNET_SYSERR; |
1300 | } | 1472 | } |
1301 | gcry_mpi_release (q); | 1473 | gcry_ctx_release (ctx); |
1302 | 1474 | ||
1303 | /* finally, verify the signature */ | 1475 | /* finally, verify the signature */ |
1304 | rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr); | 1476 | rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr); |
@@ -1308,7 +1480,7 @@ GNUNET_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose *purpose, | |||
1308 | if (rc) | 1480 | if (rc) |
1309 | { | 1481 | { |
1310 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1482 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1311 | _("RSA signature verification failed at %s:%d: %s\n"), __FILE__, | 1483 | _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__, |
1312 | __LINE__, gcry_strerror (rc)); | 1484 | __LINE__, gcry_strerror (rc)); |
1313 | return GNUNET_SYSERR; | 1485 | return GNUNET_SYSERR; |
1314 | } | 1486 | } |