aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/conversation/conversation.h2
-rw-r--r--src/conversation/gnunet-service-conversation.c8
-rw-r--r--src/gnsrecord/gnsrecord_misc.c11
-rw-r--r--src/identity/identity_api.c164
-rw-r--r--src/include/gnunet_identity_service.h215
5 files changed, 389 insertions, 11 deletions
diff --git a/src/conversation/conversation.h b/src/conversation/conversation.h
index 9eedbeb91..d244f5163 100644
--- a/src/conversation/conversation.h
+++ b/src/conversation/conversation.h
@@ -313,7 +313,7 @@ struct CadetPhoneRingMessage
313 /** 313 /**
314 * Signature over a `struct CadetPhoneRingInfoPS` 314 * Signature over a `struct CadetPhoneRingInfoPS`
315 */ 315 */
316 struct GNUNET_CRYPTO_EcdsaSignature signature; 316 struct GNUNET_IDENTITY_Signature signature;
317}; 317};
318 318
319 319
diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c
index b1a629217..5c8b573a2 100644
--- a/src/conversation/gnunet-service-conversation.c
+++ b/src/conversation/gnunet-service-conversation.c
@@ -752,10 +752,10 @@ handle_cadet_ring_message (void *cls, const struct CadetPhoneRingMessage *msg)
752 rs.expiration_time = msg->expiration_time; 752 rs.expiration_time = msg->expiration_time;
753 753
754 if (GNUNET_OK != 754 if (GNUNET_OK !=
755 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, 755 GNUNET_IDENTITY_public_key_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING,
756 &rs, 756 &rs,
757 &msg->signature, 757 &msg->signature,
758 &msg->caller_id.ecdsa_key)) 758 &msg->caller_id))
759 { 759 {
760 GNUNET_break_op (0); 760 GNUNET_break_op (0);
761 destroy_line_cadet_channels (ch); 761 destroy_line_cadet_channels (ch);
@@ -1138,9 +1138,7 @@ handle_client_call_message (void *cls, const struct ClientCallMessage *msg)
1138 e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); 1138 e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING);
1139 GNUNET_IDENTITY_key_get_public (&msg->caller_id, &ring->caller_id); 1139 GNUNET_IDENTITY_key_get_public (&msg->caller_id, &ring->caller_id);
1140 ring->expiration_time = rs.expiration_time; 1140 ring->expiration_time = rs.expiration_time;
1141 GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id.ecdsa_key, 1141 GNUNET_IDENTITY_private_key_sign(&msg->caller_id, &rs, &ring->signature);
1142 &rs,
1143 &ring->signature);
1144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n"); 1142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
1145 GNUNET_MQ_send (ch->mq, e); 1143 GNUNET_MQ_send (ch->mq, e);
1146 GNUNET_SERVICE_client_continue (line->client); 1144 GNUNET_SERVICE_client_continue (line->client);
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
index ba8803850..2e00141a3 100644
--- a/src/gnsrecord/gnsrecord_misc.c
+++ b/src/gnsrecord/gnsrecord_misc.c
@@ -282,9 +282,9 @@ GNUNET_GNSRECORD_identity_from_data (const char *data,
282 return GNUNET_SYSERR; 282 return GNUNET_SYSERR;
283 if (data_size > sizeof (struct GNUNET_IDENTITY_PublicKey)) 283 if (data_size > sizeof (struct GNUNET_IDENTITY_PublicKey))
284 return GNUNET_SYSERR; 284 return GNUNET_SYSERR;
285 key->type = type; 285 return (GNUNET_IDENTITY_read_key_from_buffer(key, data, data_size) == data_size?
286 memcpy (key, data, data_size); 286 GNUNET_OK :
287 return GNUNET_OK; 287 GNUNET_SYSERR);
288} 288}
289 289
290enum GNUNET_GenericReturnValue 290enum GNUNET_GenericReturnValue
@@ -299,8 +299,9 @@ GNUNET_GNSRECORD_data_from_identity (const struct
299 if (0 == *data_size) 299 if (0 == *data_size)
300 return GNUNET_SYSERR; 300 return GNUNET_SYSERR;
301 *data = GNUNET_malloc (*data_size); 301 *data = GNUNET_malloc (*data_size);
302 memcpy (*data, key, *data_size); 302 return (GNUNET_IDENTITY_write_key_to_buffer(key, data, *data_size) == *data_size?
303 return GNUNET_OK; 303 GNUNET_OK :
304 GNUNET_SYSERR);
304} 305}
305 306
306 307
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 213b6966e..242527c23 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -990,6 +990,170 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key)
990} 990}
991 991
992 992
993ssize_t
994GNUNET_IDENTITY_signature_get_length (const struct GNUNET_IDENTITY_Signature *sig)
995{
996 switch (ntohl (sig->type))
997 {
998 case GNUNET_IDENTITY_TYPE_ECDSA:
999 return sizeof (sig->type) + sizeof (sig->ecdsa_signature);
1000 break;
1001 case GNUNET_IDENTITY_TYPE_EDDSA:
1002 return sizeof (sig->type) + sizeof (sig->eddsa_signature);
1003 break;
1004 default:
1005 GNUNET_break (0);
1006 }
1007 return -1;
1008}
1009
1010
1011ssize_t
1012GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key,
1013 const void* buffer,
1014 size_t len)
1015{
1016 if (len < sizeof (key->type))
1017 return -1;
1018 GNUNET_memcpy(& (key->type), buffer, sizeof (key->type));
1019 const ssize_t length = GNUNET_IDENTITY_key_get_length(key);
1020 if (len < length)
1021 return -1;
1022 if (length < 0)
1023 return -2;
1024 GNUNET_memcpy(key, buffer, length);
1025 return length;
1026}
1027
1028
1029ssize_t
1030GNUNET_IDENTITY_write_key_to_buffer (const struct GNUNET_IDENTITY_PublicKey *key,
1031 void* buffer,
1032 size_t len)
1033{
1034 const ssize_t length = GNUNET_IDENTITY_key_get_length(key);
1035 if (len < length)
1036 return -1;
1037 if (length < 0)
1038 return -2;
1039 GNUNET_memcpy(buffer, key, length);
1040 return length;
1041}
1042
1043
1044int
1045GNUNET_IDENTITY_private_key_sign_ (const struct GNUNET_IDENTITY_PrivateKey *priv,
1046 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
1047 struct GNUNET_IDENTITY_Signature *sig)
1048{
1049 sig->type = priv->type;
1050 switch (ntohl (priv->type))
1051 {
1052 case GNUNET_IDENTITY_TYPE_ECDSA:
1053 return GNUNET_CRYPTO_ecdsa_sign_ (& (priv->ecdsa_key), purpose, & (sig->ecdsa_signature));
1054 break;
1055 case GNUNET_IDENTITY_TYPE_EDDSA:
1056 return GNUNET_CRYPTO_eddsa_sign_ (& (priv->eddsa_key), purpose, & (sig->eddsa_signature));
1057 break;
1058 default:
1059 GNUNET_break (0);
1060 }
1061
1062 return GNUNET_SYSERR;
1063}
1064
1065
1066int
1067GNUNET_IDENTITY_public_key_verify_ (uint32_t purpose,
1068 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1069 const struct GNUNET_IDENTITY_Signature *sig,
1070 const struct GNUNET_IDENTITY_PublicKey *pub)
1071{
1072 /* check type matching of 'sig' and 'pub' */
1073 GNUNET_assert (ntohl (pub->type) == ntohl (sig->type));
1074 switch (ntohl (pub->type))
1075 {
1076 case GNUNET_IDENTITY_TYPE_ECDSA:
1077 return GNUNET_CRYPTO_ecdsa_verify_ (purpose, validate, & (sig->ecdsa_signature), & (pub->ecdsa_key));
1078 break;
1079 case GNUNET_IDENTITY_TYPE_EDDSA:
1080 return GNUNET_CRYPTO_eddsa_verify_ (purpose, validate, & (sig->eddsa_signature), & (pub->eddsa_key));
1081 break;
1082 default:
1083 GNUNET_break (0);
1084 }
1085
1086 return GNUNET_SYSERR;
1087}
1088
1089
1090ssize_t
1091GNUNET_IDENTITY_public_key_encrypt(const void *block,
1092 size_t size,
1093 const struct GNUNET_IDENTITY_PublicKey *pub,
1094 struct GNUNET_CRYPTO_EcdhePublicKey *ecc,
1095 void *result)
1096{
1097 struct GNUNET_CRYPTO_EcdhePrivateKey pk;
1098 GNUNET_CRYPTO_ecdhe_key_create(&pk);
1099 struct GNUNET_HashCode hash;
1100 switch (ntohl (pub->type))
1101 {
1102 case GNUNET_IDENTITY_TYPE_ECDSA:
1103 if (GNUNET_CRYPTO_ecdh_ecdsa(&pk, &(pub->ecdsa_key), &hash) == GNUNET_SYSERR)
1104 return -1;
1105 break;
1106 case GNUNET_IDENTITY_TYPE_EDDSA:
1107 if (GNUNET_CRYPTO_ecdh_eddsa(&pk, &(pub->eddsa_key), &hash) == GNUNET_SYSERR)
1108 return -1;
1109 break;
1110 default:
1111 return -1;
1112 }
1113 GNUNET_CRYPTO_ecdhe_key_get_public(&pk, ecc);
1114 GNUNET_CRYPTO_ecdhe_key_clear(&pk);
1115 struct GNUNET_CRYPTO_SymmetricSessionKey key;
1116 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1117 GNUNET_CRYPTO_hash_to_aes_key(&hash, &key, &iv);
1118 GNUNET_CRYPTO_zero_keys(&hash, sizeof(hash));
1119 const ssize_t encrypted = GNUNET_CRYPTO_symmetric_encrypt(block, size, &key, &iv, result);
1120 GNUNET_CRYPTO_zero_keys(&key, sizeof(key));
1121 GNUNET_CRYPTO_zero_keys(&iv, sizeof(iv));
1122 return encrypted;
1123}
1124
1125
1126ssize_t
1127GNUNET_IDENTITY_private_key_decrypt(const void *block,
1128 size_t size,
1129 const struct GNUNET_IDENTITY_PrivateKey *priv,
1130 const struct GNUNET_CRYPTO_EcdhePublicKey *ecc,
1131 void *result) {
1132 struct GNUNET_HashCode hash;
1133 switch (ntohl (priv->type))
1134 {
1135 case GNUNET_IDENTITY_TYPE_ECDSA:
1136 if (GNUNET_CRYPTO_ecdsa_ecdh(&(priv->ecdsa_key), ecc, &hash) == GNUNET_SYSERR)
1137 return -1;
1138 break;
1139 case GNUNET_IDENTITY_TYPE_EDDSA:
1140 if (GNUNET_CRYPTO_eddsa_ecdh(&(priv->eddsa_key), ecc, &hash) == GNUNET_SYSERR)
1141 return -1;
1142 break;
1143 default:
1144 return -1;
1145 }
1146 struct GNUNET_CRYPTO_SymmetricSessionKey key;
1147 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1148 GNUNET_CRYPTO_hash_to_aes_key(&hash, &key, &iv);
1149 GNUNET_CRYPTO_zero_keys(&hash, sizeof(hash));
1150 const ssize_t decrypted = GNUNET_CRYPTO_symmetric_decrypt(block, size, &key, &iv, result);
1151 GNUNET_CRYPTO_zero_keys(&key, sizeof(key));
1152 GNUNET_CRYPTO_zero_keys(&iv, sizeof(iv));
1153 return decrypted;
1154}
1155
1156
993char * 1157char *
994GNUNET_IDENTITY_public_key_to_string (const struct 1158GNUNET_IDENTITY_public_key_to_string (const struct
995 GNUNET_IDENTITY_PublicKey *key) 1159 GNUNET_IDENTITY_PublicKey *key)
diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h
index 17714fec4..8084a3a98 100644
--- a/src/include/gnunet_identity_service.h
+++ b/src/include/gnunet_identity_service.h
@@ -138,6 +138,33 @@ struct GNUNET_IDENTITY_PublicKey
138 138
139 139
140/** 140/**
141 * An identity signature as per LSD0001.
142 */
143struct GNUNET_IDENTITY_Signature
144{
145 /**
146 * Type of signature.
147 * Defined by the GNS zone type value.
148 * In NBO.
149 */
150 uint32_t type;
151
152 union
153 {
154 /**
155 * An ECDSA signature
156 */
157 struct GNUNET_CRYPTO_EcdsaSignature ecdsa_signature;
158
159 /**
160 * AN EdDSA signature
161 */
162 struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
163 };
164};
165
166
167/**
141 * Handle for an operation with the identity service. 168 * Handle for an operation with the identity service.
142 */ 169 */
143struct GNUNET_IDENTITY_Operation; 170struct GNUNET_IDENTITY_Operation;
@@ -379,6 +406,194 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key);
379 406
380 407
381/** 408/**
409 * Get the compacted length of a #GNUNET_IDENTITY_Signature.
410 * Compacted means that it returns the minimum number of bytes this
411 * signature is long, as opposed to the union structure inside
412 * #GNUNET_IDENTITY_Signature.
413 * Useful for compact serializations.
414 *
415 * @param sig the signature.
416 * @return -1 on error, else the compacted length of the signature.
417 */
418ssize_t
419GNUNET_IDENTITY_signature_get_length (const struct GNUNET_IDENTITY_Signature *sig);
420
421
422/**
423 * Reads a #GNUNET_IDENTITY_PublicKey from a compact buffer.
424 * The buffer has to contain at least the compacted length of
425 * a #GNUNET_IDENTITY_PublicKey bytes.
426 * If the buffer is too small, the function returns -1 as error.
427 * If the buffer does not contain a valid key, it returns -2 as error.
428 *
429 * @param key the key
430 * @param buffer the buffer
431 * @param len the length of buffer
432 * @return -1 or -2 on error, else the amount of bytes read from the buffer
433 */
434ssize_t
435GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key,
436 const void* buffer,
437 size_t len);
438
439
440/**
441 * Writes a #GNUNET_IDENTITY_PublicKey to a compact buffer.
442 * The buffer requires space for at least the compacted length of
443 * a #GNUNET_IDENTITY_PublicKey in bytes.
444 * If the buffer is too small, the function returns -1 as error.
445 * If the key is not valid, it returns -2 as error.
446 *
447 * @param key the key
448 * @param buffer the buffer
449 * @param len the length of buffer
450 * @return -1 or -2 on error, else the amount of bytes written to the buffer
451 */
452ssize_t
453GNUNET_IDENTITY_write_key_to_buffer (const struct GNUNET_IDENTITY_PublicKey *key,
454 void* buffer,
455 size_t len);
456
457
458/**
459 * @brief Sign a given block.
460 *
461 * The @a purpose data is the beginning of the data of which the signature is
462 * to be created. The `size` field in @a purpose must correctly indicate the
463 * number of bytes of the data structure, including its header. If possible,
464 * use #GNUNET_IDENTITY_private_key_sign() instead of this function.
465 *
466 * @param priv private key to use for the signing
467 * @param purpose what to sign (size, purpose)
468 * @param[out] sig where to write the signature
469 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
470 */
471int
472GNUNET_IDENTITY_private_key_sign_ (const struct GNUNET_IDENTITY_PrivateKey *priv,
473 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
474 struct GNUNET_IDENTITY_Signature *sig);
475
476
477/**
478 * @brief Sign a given block with #GNUNET_IDENTITY_PrivateKey.
479 *
480 * The @a ps data must be a fixed-size struct for which the signature is to be
481 * created. The `size` field in @a ps->purpose must correctly indicate the
482 * number of bytes of the data structure, including its header.
483 *
484 * @param priv private key to use for the signing
485 * @param ps packed struct with what to sign, MUST begin with a purpose
486 * @param[out] sig where to write the signature
487 */
488#define GNUNET_IDENTITY_private_key_sign(priv,ps,sig) do { \
489 /* check size is set correctly */ \
490 GNUNET_assert (htonl ((ps)->purpose.size) == sizeof (*(ps))); \
491 /* check 'ps' begins with the purpose */ \
492 GNUNET_static_assert (((void*) (ps)) == \
493 ((void*) &(ps)->purpose)); \
494 GNUNET_assert (GNUNET_OK == \
495 GNUNET_IDENTITY_private_key_sign_ (priv, \
496 &(ps)->purpose, \
497 sig)); \
498} while (0)
499
500
501/**
502 * @brief Verify a given signature.
503 *
504 * The @a validate data is the beginning of the data of which the signature
505 * is to be verified. The `size` field in @a validate must correctly indicate
506 * the number of bytes of the data structure, including its header. If @a
507 * purpose does not match the purpose given in @a validate (the latter must be
508 * in big endian), signature verification fails. If possible,
509 * use #GNUNET_IDENTITY_public_key_verify() instead of this function (only if @a validate
510 * is not fixed-size, you must use this function directly).
511 *
512 * @param purpose what is the purpose that the signature should have?
513 * @param validate block to validate (size, purpose, data)
514 * @param sig signature that is being validated
515 * @param pub public key of the signer
516 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
517 */
518int
519GNUNET_IDENTITY_public_key_verify_ (uint32_t purpose,
520 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
521 const struct GNUNET_IDENTITY_Signature *sig,
522 const struct GNUNET_IDENTITY_PublicKey *pub);
523
524
525/**
526 * @brief Verify a given signature with #GNUNET_IDENTITY_PublicKey.
527 *
528 * The @a ps data must be a fixed-size struct for which the signature is to be
529 * created. The `size` field in @a ps->purpose must correctly indicate the
530 * number of bytes of the data structure, including its header.
531 *
532 * @param purp purpose of the signature, must match 'ps->purpose.purpose'
533 * (except in host byte order)
534 * @param ps packed struct with what to sign, MUST begin with a purpose
535 * @param sig where to read the signature from
536 * @param pub public key to use for the verifying
537 */
538#define GNUNET_IDENTITY_public_key_verify(purp,ps,sig,pub) ({ \
539 /* check size is set correctly */ \
540 GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \
541 /* check 'ps' begins with the purpose */ \
542 GNUNET_static_assert (((void*) (ps)) == \
543 ((void*) &(ps)->purpose)); \
544 GNUNET_IDENTITY_public_key_verify_(purp, \
545 &(ps)->purpose, \
546 sig, \
547 pub); \
548 })
549
550
551/**
552 * Encrypt a block with #GNUNET_IDENTITY_PublicKey and derives a
553 * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption
554 * using ecdh to derive a symmetric key.
555 *
556 * @param block the block to encrypt
557 * @param size the size of the @a block
558 * @param pub public key to use for ecdh
559 * @param ecc where to write the ecc public key
560 * @param result the output parameter in which to store the encrypted result
561 * can be the same or overlap with @c block
562 * @returns the size of the encrypted block, -1 for errors.
563 * Due to the use of CFB and therefore an effective stream cipher,
564 * this size should be the same as @c len.
565 */
566ssize_t
567GNUNET_IDENTITY_public_key_encrypt(const void *block,
568 size_t size,
569 const struct GNUNET_IDENTITY_PublicKey *pub,
570 struct GNUNET_CRYPTO_EcdhePublicKey *ecc,
571 void *result);
572
573
574/**
575 * Decrypt a given block with #GNUNET_IDENTITY_PrivateKey and a given
576 * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key.
577 *
578 * @param block the data to decrypt, encoded as returned by encrypt
579 * @param size the size of the @a block to decrypt
580 * @param priv private key to use for ecdh
581 * @param ecc the ecc public key
582 * @param result address to store the result at
583 * can be the same or overlap with @c block
584 * @return -1 on failure, size of decrypted block on success.
585 * Due to the use of CFB and therefore an effective stream cipher,
586 * this size should be the same as @c size.
587 */
588ssize_t
589GNUNET_IDENTITY_private_key_decrypt(const void *block,
590 size_t size,
591 const struct GNUNET_IDENTITY_PrivateKey *priv,
592 const struct GNUNET_CRYPTO_EcdhePublicKey *ecc,
593 void *result);
594
595
596/**
382 * Creates a (Base32) string representation of the public key. 597 * Creates a (Base32) string representation of the public key.
383 * The resulting string encodes a compacted representation of the key. 598 * The resulting string encodes a compacted representation of the key.
384 * See also #GNUNET_IDENTITY_key_get_length. 599 * See also #GNUNET_IDENTITY_key_get_length.