diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-27 21:01:13 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-27 21:01:13 +0200 |
commit | f7e0dfea0966f0ae9a4185206885d3a61895b759 (patch) | |
tree | eeeba47f96972b3e619cd038f488f0639062977d /src/reclaim/oidc_helper.c | |
parent | 7f50a089e5308bc7691704683dea805258f6c0b2 (diff) | |
download | gnunet-f7e0dfea0966f0ae9a4185206885d3a61895b759.tar.gz gnunet-f7e0dfea0966f0ae9a4185206885d3a61895b759.zip |
RECLAIM/OIDC: encrypt authorizaion code payload
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r-- | src/reclaim/oidc_helper.c | 160 |
1 files changed, 143 insertions, 17 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 56a4b17a4..89e0920f0 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -292,6 +292,86 @@ base64_encode (const char *data, size_t data_size) | |||
292 | } | 292 | } |
293 | 293 | ||
294 | 294 | ||
295 | static void | ||
296 | derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
297 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
298 | struct GNUNET_HashCode *key_material) | ||
299 | { | ||
300 | static const char ctx_key[] = "reclaim-aes-ctx-key"; | ||
301 | static const char ctx_iv[] = "reclaim-aes-ctx-iv"; | ||
302 | GNUNET_CRYPTO_kdf (key, | ||
303 | sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
304 | ctx_key, | ||
305 | strlen (ctx_key), | ||
306 | &key_material, | ||
307 | sizeof (key_material), | ||
308 | NULL); | ||
309 | GNUNET_CRYPTO_kdf (iv, | ||
310 | sizeof ( | ||
311 | struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
312 | ctx_iv, | ||
313 | strlen (ctx_iv), | ||
314 | &key_material, | ||
315 | sizeof (key_material), | ||
316 | NULL); | ||
317 | } | ||
318 | |||
319 | |||
320 | static void | ||
321 | calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
322 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
323 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
324 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) | ||
325 | { | ||
326 | struct GNUNET_HashCode key_material; | ||
327 | GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material); | ||
328 | derive_aes_key (key, iv, &key_material); | ||
329 | } | ||
330 | |||
331 | |||
332 | static void | ||
333 | calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
334 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
335 | const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
336 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) | ||
337 | { | ||
338 | struct GNUNET_HashCode key_material; | ||
339 | GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material); | ||
340 | derive_aes_key (key, iv, &key_material); | ||
341 | } | ||
342 | |||
343 | |||
344 | static void | ||
345 | decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | ||
346 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, | ||
347 | const char *ct, | ||
348 | size_t ct_len, | ||
349 | char *buf) | ||
350 | { | ||
351 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
352 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
353 | |||
354 | calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub); | ||
355 | GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf)); | ||
356 | } | ||
357 | |||
358 | |||
359 | static void | ||
360 | encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, | ||
361 | const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, | ||
362 | const char *payload, | ||
363 | size_t payload_len, | ||
364 | char *buf) | ||
365 | { | ||
366 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
367 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
368 | |||
369 | calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); | ||
370 | GNUNET_break ( | ||
371 | GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); | ||
372 | } | ||
373 | |||
374 | |||
295 | /** | 375 | /** |
296 | * Builds an OIDC authorization code including | 376 | * Builds an OIDC authorization code including |
297 | * a reclaim ticket and nonce | 377 | * a reclaim ticket and nonce |
@@ -309,6 +389,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
309 | const char *nonce_str) | 389 | const char *nonce_str) |
310 | { | 390 | { |
311 | char *code_payload; | 391 | char *code_payload; |
392 | char *plaintext; | ||
312 | char *attrs_ser; | 393 | char *attrs_ser; |
313 | char *code_str; | 394 | char *code_str; |
314 | char *buf_ptr; | 395 | char *buf_ptr; |
@@ -318,6 +399,8 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
318 | uint32_t nonce; | 399 | uint32_t nonce; |
319 | uint32_t nonce_tmp; | 400 | uint32_t nonce_tmp; |
320 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 401 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
402 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv; | ||
403 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub; | ||
321 | 404 | ||
322 | attrs_ser = NULL; | 405 | attrs_ser = NULL; |
323 | signature_payload_len = | 406 | signature_payload_len = |
@@ -333,19 +416,15 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
333 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser); | 416 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser); |
334 | } | 417 | } |
335 | code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 418 | code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
419 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | ||
336 | signature_payload_len + | 420 | signature_payload_len + |
337 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 421 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
338 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 422 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
339 | "Length of data to encode: %lu\n", | 423 | "Length of data to encode: %lu\n", |
340 | code_payload_len); | 424 | code_payload_len); |
341 | code_payload = GNUNET_malloc (code_payload_len); | 425 | plaintext = GNUNET_malloc (signature_payload_len); |
342 | GNUNET_assert (NULL != code_payload); | ||
343 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; | ||
344 | purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
345 | signature_payload_len); | ||
346 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); | ||
347 | // First, copy ticket | 426 | // First, copy ticket |
348 | buf_ptr = (char *) &purpose[1]; | 427 | buf_ptr = plaintext; |
349 | memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); | 428 | memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); |
350 | buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket); | 429 | buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket); |
351 | // Then copy nonce | 430 | // Then copy nonce |
@@ -356,12 +435,14 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
356 | { | 435 | { |
357 | GNUNET_break (0); | 436 | GNUNET_break (0); |
358 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); | 437 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); |
359 | GNUNET_free (code_payload); | 438 | GNUNET_free (plaintext); |
360 | GNUNET_free_non_null (attrs_ser); | 439 | GNUNET_free_non_null (attrs_ser); |
361 | return NULL; | 440 | return NULL; |
362 | } | 441 | } |
363 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 442 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
364 | "Got nonce: %u from %s\n", nonce, nonce_str); | 443 | "Got nonce: %u from %s\n", |
444 | nonce, | ||
445 | nonce_str); | ||
365 | } | 446 | } |
366 | nonce_tmp = htonl (nonce); | 447 | nonce_tmp = htonl (nonce); |
367 | memcpy (buf_ptr, &nonce_tmp, sizeof (uint32_t)); | 448 | memcpy (buf_ptr, &nonce_tmp, sizeof (uint32_t)); |
@@ -371,7 +452,32 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
371 | { | 452 | { |
372 | memcpy (buf_ptr, attrs_ser, attr_list_len); | 453 | memcpy (buf_ptr, attrs_ser, attr_list_len); |
373 | buf_ptr += attr_list_len; | 454 | buf_ptr += attr_list_len; |
455 | GNUNET_free (attrs_ser); | ||
374 | } | 456 | } |
457 | // Generate ECDH key | ||
458 | ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create (); | ||
459 | GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub); | ||
460 | // Initialize code payload | ||
461 | code_payload = GNUNET_malloc (code_payload_len); | ||
462 | GNUNET_assert (NULL != code_payload); | ||
463 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; | ||
464 | purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
465 | sizeof (ecdh_pub) + signature_payload_len); | ||
466 | purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); | ||
467 | // Store pubkey | ||
468 | buf_ptr = (char *) &purpose[1]; | ||
469 | memcpy (buf_ptr, &ecdh_pub, sizeof (ecdh_pub)); | ||
470 | buf_ptr += sizeof (ecdh_pub); | ||
471 | // Encrypt plaintext and store | ||
472 | encrypt_payload (&ticket->audience, | ||
473 | ecdh_priv, | ||
474 | plaintext, | ||
475 | signature_payload_len, | ||
476 | buf_ptr); | ||
477 | GNUNET_free (ecdh_priv); | ||
478 | GNUNET_free (plaintext); | ||
479 | buf_ptr += signature_payload_len; | ||
480 | // Sign and store signature | ||
375 | if (GNUNET_SYSERR == | 481 | if (GNUNET_SYSERR == |
376 | GNUNET_CRYPTO_ecdsa_sign (issuer, | 482 | GNUNET_CRYPTO_ecdsa_sign (issuer, |
377 | purpose, | 483 | purpose, |
@@ -381,12 +487,10 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
381 | GNUNET_break (0); | 487 | GNUNET_break (0); |
382 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); | 488 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); |
383 | GNUNET_free (code_payload); | 489 | GNUNET_free (code_payload); |
384 | GNUNET_free_non_null (attrs_ser); | ||
385 | return NULL; | 490 | return NULL; |
386 | } | 491 | } |
387 | code_str = base64_encode (code_payload, code_payload_len); | 492 | code_str = base64_encode (code_payload, code_payload_len); |
388 | GNUNET_free (code_payload); | 493 | GNUNET_free (code_payload); |
389 | GNUNET_free_non_null (attrs_ser); | ||
390 | return code_str; | 494 | return code_str; |
391 | } | 495 | } |
392 | 496 | ||
@@ -404,7 +508,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
404 | * @return GNUNET_OK if successful, else GNUNET_SYSERR | 508 | * @return GNUNET_OK if successful, else GNUNET_SYSERR |
405 | */ | 509 | */ |
406 | int | 510 | int |
407 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, | 511 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, |
408 | const char *code, | 512 | const char *code, |
409 | struct GNUNET_RECLAIM_Ticket *ticket, | 513 | struct GNUNET_RECLAIM_Ticket *ticket, |
410 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, | 514 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, |
@@ -412,19 +516,23 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, | |||
412 | { | 516 | { |
413 | char *code_payload; | 517 | char *code_payload; |
414 | char *ptr; | 518 | char *ptr; |
519 | char *plaintext; | ||
415 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 520 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
416 | struct GNUNET_CRYPTO_EcdsaSignature *signature; | 521 | struct GNUNET_CRYPTO_EcdsaSignature *signature; |
522 | struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; | ||
523 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub; | ||
417 | size_t code_payload_len; | 524 | size_t code_payload_len; |
418 | size_t attrs_ser_len; | 525 | size_t attrs_ser_len; |
419 | size_t signature_offset; | 526 | size_t signature_offset; |
527 | size_t plaintext_len; | ||
420 | uint32_t nonce = 0; | 528 | uint32_t nonce = 0; |
421 | 529 | ||
422 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Trying to decode `%s'\n", code); | 530 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); |
423 | code_payload = NULL; | 531 | code_payload = NULL; |
424 | code_payload_len = | 532 | code_payload_len = |
425 | GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); | 533 | GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); |
426 | |||
427 | if (code_payload_len < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 534 | if (code_payload_len < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
535 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | ||
428 | sizeof (struct GNUNET_RECLAIM_Ticket) + | 536 | sizeof (struct GNUNET_RECLAIM_Ticket) + |
429 | sizeof (uint32_t) + | 537 | sizeof (uint32_t) + |
430 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)) | 538 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)) |
@@ -438,24 +546,39 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, | |||
438 | attrs_ser_len = code_payload_len; | 546 | attrs_ser_len = code_payload_len; |
439 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); | 547 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); |
440 | ptr = (char *) &purpose[1]; | 548 | ptr = (char *) &purpose[1]; |
549 | // Public ECDH key | ||
550 | ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; | ||
551 | ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); | ||
552 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); | ||
553 | |||
554 | // Decrypt ciphertext | ||
555 | plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | ||
556 | plaintext = GNUNET_malloc (plaintext_len); | ||
557 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); | ||
558 | ptr = plaintext; | ||
559 | // Ticket | ||
441 | *ticket = *((struct GNUNET_RECLAIM_Ticket *) ptr); | 560 | *ticket = *((struct GNUNET_RECLAIM_Ticket *) ptr); |
442 | attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket); | 561 | attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket); |
443 | ptr += sizeof (struct GNUNET_RECLAIM_Ticket); | 562 | ptr += sizeof (struct GNUNET_RECLAIM_Ticket); |
563 | // Nonce | ||
444 | nonce = ntohl (*((uint32_t *) ptr)); | 564 | nonce = ntohl (*((uint32_t *) ptr)); |
445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 565 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); |
446 | "Got nonce: %u\n", nonce); | ||
447 | attrs_ser_len -= sizeof (uint32_t); | 566 | attrs_ser_len -= sizeof (uint32_t); |
448 | ptr += sizeof (uint32_t); | 567 | ptr += sizeof (uint32_t); |
568 | // Attributes | ||
449 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 569 | attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
450 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (ptr, attrs_ser_len); | 570 | *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (ptr, attrs_ser_len); |
571 | // Signature | ||
451 | signature_offset = | 572 | signature_offset = |
452 | code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 573 | code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
453 | signature = | 574 | signature = |
454 | (struct GNUNET_CRYPTO_EcdsaSignature *) &code_payload[signature_offset]; | 575 | (struct GNUNET_CRYPTO_EcdsaSignature *) &code_payload[signature_offset]; |
455 | if (0 != GNUNET_memcmp (audience, &ticket->audience)) | 576 | GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); |
577 | if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) | ||
456 | { | 578 | { |
457 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); | 579 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); |
458 | GNUNET_free (code_payload); | 580 | GNUNET_free (code_payload); |
581 | GNUNET_free (plaintext); | ||
459 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 582 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
460 | "Audience in ticket does not match client!\n"); | 583 | "Audience in ticket does not match client!\n"); |
461 | return GNUNET_SYSERR; | 584 | return GNUNET_SYSERR; |
@@ -468,12 +591,15 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, | |||
468 | { | 591 | { |
469 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); | 592 | GNUNET_RECLAIM_ATTRIBUTE_list_destroy (*attrs); |
470 | GNUNET_free (code_payload); | 593 | GNUNET_free (code_payload); |
594 | GNUNET_free (plaintext); | ||
471 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); | 595 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); |
472 | return GNUNET_SYSERR; | 596 | return GNUNET_SYSERR; |
473 | } | 597 | } |
474 | *nonce_str = NULL; | 598 | *nonce_str = NULL; |
475 | if (nonce != 0) | 599 | if (nonce != 0) |
476 | GNUNET_asprintf (nonce_str, "%u", nonce); | 600 | GNUNET_asprintf (nonce_str, "%u", nonce); |
601 | GNUNET_free (code_payload); | ||
602 | GNUNET_free (plaintext); | ||
477 | return GNUNET_OK; | 603 | return GNUNET_OK; |
478 | } | 604 | } |
479 | 605 | ||