46 |
46 |
#include <libxml/parserInternals.h>
|
47 |
47 |
#include <libxml/xmlIO.h>
|
48 |
48 |
|
49 |
|
#include <openssl/pem.h>
|
50 |
|
#include <openssl/sha.h>
|
51 |
|
#include <openssl/engine.h>
|
52 |
|
#include <openssl/hmac.h>
|
53 |
49 |
#include <openssl/evp.h>
|
54 |
50 |
|
55 |
51 |
#include <xmlsec/base64.h>
|
... | ... | |
60 |
56 |
#include <xmlsec/errors.h>
|
61 |
57 |
#include <xmlsec/openssl/x509.h>
|
62 |
58 |
#include <xmlsec/openssl/crypto.h>
|
|
59 |
#include <xmlsec/openssl/evp.h>
|
63 |
60 |
|
64 |
61 |
#include <zlib.h>
|
65 |
62 |
|
... | ... | |
481 |
478 |
lasso_query_sign(char *query, LassoSignatureContext context)
|
482 |
479 |
{
|
483 |
480 |
char *digest = NULL; /* 160 bit buffer */
|
484 |
|
RSA *rsa = NULL;
|
485 |
|
DSA *dsa = NULL;
|
486 |
481 |
unsigned char *sigret = NULL;
|
487 |
|
unsigned int siglen = 0;
|
|
482 |
size_t siglen = 0;
|
488 |
483 |
xmlChar *b64_sigret = NULL, *e_b64_sigret = NULL;
|
489 |
484 |
char *new_query = NULL, *s_new_query = NULL;
|
490 |
485 |
int status = 0;
|
491 |
486 |
const xmlChar *algo_href = NULL;
|
492 |
|
char *hmac_key;
|
|
487 |
unsigned char *hmac_key;
|
493 |
488 |
size_t hmac_key_length;
|
494 |
|
const EVP_MD *md = NULL;
|
495 |
489 |
xmlSecKey *key;
|
496 |
490 |
xmlSecKeyData *key_data;
|
497 |
|
unsigned int sigret_size = 0;
|
498 |
491 |
LassoSignatureMethod sign_method;
|
499 |
|
lasso_error_t rc = 0;
|
|
492 |
lasso_error_t rc = 0;
|
|
493 |
|
|
494 |
const EVP_MD *md = NULL;
|
|
495 |
EVP_MD_CTX *evp_md_ctx = NULL;
|
|
496 |
EVP_PKEY *pkey = NULL;
|
|
497 |
EVP_PKEY *hmac_pkey = NULL;
|
500 |
498 |
|
501 |
499 |
g_return_val_if_fail(query != NULL, NULL);
|
502 |
500 |
g_return_val_if_fail(lasso_ok_signature_method(context.signature_method), NULL);
|
... | ... | |
546 |
544 |
xmlFree(BAD_CAST t);
|
547 |
545 |
}
|
548 |
546 |
|
549 |
|
/* build buffer digest */
|
|
547 |
/* define the digest algorithm */
|
550 |
548 |
switch (sign_method) {
|
551 |
549 |
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
552 |
550 |
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
553 |
|
digest = lasso_sha1(new_query);
|
|
551 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
|
552 |
md = EVP_sha1();
|
554 |
553 |
break;
|
555 |
554 |
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
556 |
|
digest = lasso_sha256(new_query);
|
|
555 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
|
556 |
md = EVP_sha256();
|
557 |
557 |
break;
|
558 |
558 |
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
559 |
|
digest = lasso_sha384(new_query);
|
|
559 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
|
560 |
md = EVP_sha384();
|
560 |
561 |
break;
|
561 |
562 |
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
562 |
|
digest = lasso_sha512(new_query);
|
563 |
|
default:
|
|
563 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA512:
|
|
564 |
md = EVP_sha512();
|
564 |
565 |
break;
|
|
566 |
case LASSO_SIGNATURE_METHOD_NONE:
|
|
567 |
case LASSO_SIGNATURE_METHOD_LAST:
|
|
568 |
g_assert_not_reached();
|
565 |
569 |
}
|
|
570 |
|
|
571 |
/* Get the signture key */
|
566 |
572 |
switch (sign_method) {
|
567 |
573 |
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
568 |
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
569 |
574 |
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
570 |
575 |
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
571 |
576 |
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
572 |
|
if (digest == NULL) {
|
573 |
|
message(G_LOG_LEVEL_CRITICAL, "Failed to build the buffer digest");
|
|
577 |
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
|
578 |
pkey = xmlSecOpenSSLEvpKeyDataGetEvp(key_data);
|
|
579 |
if (! pkey) {
|
|
580 |
message(G_LOG_LEVEL_CRITICAL, "Failed to get assymetric key");
|
574 |
581 |
goto done;
|
575 |
582 |
}
|
576 |
|
default:
|
577 |
|
break;
|
578 |
|
}
|
579 |
|
/* extract the OpenSSL key */
|
580 |
|
switch (sign_method) {
|
581 |
|
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
582 |
|
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
583 |
|
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
584 |
|
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
585 |
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key_data);
|
586 |
|
g_assert(rsa);
|
587 |
|
/* alloc memory for sigret */
|
588 |
|
sigret_size = RSA_size(rsa);
|
589 |
|
break;
|
590 |
|
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
591 |
|
dsa = xmlSecOpenSSLKeyDataDsaGetDsa(key_data);
|
592 |
|
g_assert(dsa);
|
593 |
|
/* alloc memory for sigret */
|
594 |
|
sigret_size = DSA_size(dsa);
|
595 |
583 |
break;
|
596 |
584 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
597 |
|
md = EVP_sha1();
|
598 |
|
sigret_size = EVP_MD_size(md);
|
599 |
|
break;
|
600 |
585 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
601 |
|
md = EVP_sha256();
|
602 |
|
sigret_size = EVP_MD_size(md);
|
603 |
|
break;
|
604 |
586 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
605 |
|
md = EVP_sha384();
|
606 |
|
sigret_size = EVP_MD_size(md);
|
607 |
|
break;
|
608 |
587 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA512:
|
609 |
|
md = EVP_sha512();
|
610 |
|
sigret_size = EVP_MD_size(md);
|
|
588 |
if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key,
|
|
589 |
&hmac_key_length))) {
|
|
590 |
message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc));
|
|
591 |
goto done;
|
|
592 |
}
|
|
593 |
g_assert(hmac_key);
|
|
594 |
hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, hmac_key, (int)hmac_key_length);
|
|
595 |
if (! hmac_key) {
|
|
596 |
message(G_LOG_LEVEL_CRITICAL, "EVP_PKEY_new_mac_key failed");
|
|
597 |
goto done;
|
|
598 |
}
|
|
599 |
pkey = hmac_pkey;
|
611 |
600 |
break;
|
612 |
|
default:
|
|
601 |
case LASSO_SIGNATURE_METHOD_LAST:
|
|
602 |
case LASSO_SIGNATURE_METHOD_NONE:
|
613 |
603 |
g_assert_not_reached();
|
614 |
604 |
}
|
615 |
|
sigret = (unsigned char *)g_malloc (sigret_size);
|
616 |
605 |
|
617 |
606 |
switch (sign_method) {
|
618 |
607 |
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
619 |
|
/* sign digest message */
|
620 |
|
status = RSA_sign(NID_sha1, (unsigned char*)digest, SHA_DIGEST_LENGTH, sigret,
|
621 |
|
&siglen, rsa);
|
622 |
|
break;
|
623 |
608 |
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
624 |
|
/* sign digest message */
|
625 |
|
status = RSA_sign(NID_sha256, (unsigned char*)digest, SHA256_DIGEST_LENGTH, sigret,
|
626 |
|
&siglen, rsa);
|
627 |
|
break;
|
628 |
609 |
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
629 |
|
/* sign digest message */
|
630 |
|
status = RSA_sign(NID_sha384, (unsigned char*)digest, SHA384_DIGEST_LENGTH, sigret,
|
631 |
|
&siglen, rsa);
|
632 |
|
break;
|
633 |
610 |
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
634 |
|
/* sign digest message */
|
635 |
|
status = RSA_sign(NID_sha512, (unsigned char*)digest, SHA512_DIGEST_LENGTH, sigret,
|
636 |
|
&siglen, rsa);
|
637 |
|
break;
|
638 |
611 |
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
639 |
|
status = DSA_sign(NID_sha1, (unsigned char*)digest, SHA_DIGEST_LENGTH, sigret,
|
640 |
|
&siglen, dsa);
|
641 |
|
break;
|
642 |
612 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
643 |
613 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
644 |
614 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
645 |
615 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA512:
|
646 |
|
if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key,
|
647 |
|
&hmac_key_length))) {
|
648 |
|
message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc));
|
|
616 |
evp_md_ctx = EVP_MD_CTX_create();
|
|
617 |
if (EVP_DigestSignInit(evp_md_ctx, NULL, md, NULL, pkey) <= 0) {
|
|
618 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSignInit failed");
|
649 |
619 |
goto done;
|
650 |
620 |
}
|
651 |
|
g_assert(hmac_key);
|
652 |
|
|
653 |
|
/* key should be at least 128 bits long */
|
654 |
|
if (hmac_key_length < 16) {
|
655 |
|
critical("HMAC key should be at least 128 bits long");
|
|
621 |
if (EVP_DigestSign(evp_md_ctx, NULL, &siglen, (unsigned char*)new_query, strlen(new_query)) <= 0) {
|
|
622 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed");
|
|
623 |
goto done;
|
|
624 |
}
|
|
625 |
sigret = g_malloc(siglen);
|
|
626 |
if (EVP_DigestSign(evp_md_ctx, sigret, &siglen, (unsigned char*)new_query, strlen(new_query)) <= 0) {
|
|
627 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed");
|
656 |
628 |
goto done;
|
657 |
629 |
}
|
658 |
|
|
659 |
|
HMAC(md, hmac_key, hmac_key_length, (unsigned char *)new_query,
|
660 |
|
strlen(new_query), sigret, &siglen);
|
661 |
630 |
status = 1;
|
662 |
631 |
break;
|
663 |
632 |
case LASSO_SIGNATURE_METHOD_LAST:
|
... | ... | |
665 |
634 |
g_assert_not_reached();
|
666 |
635 |
}
|
667 |
636 |
|
668 |
|
g_assert(siglen == sigret_size);
|
669 |
637 |
|
670 |
638 |
if (status == 0) {
|
671 |
639 |
goto done;
|
672 |
640 |
}
|
673 |
641 |
|
674 |
642 |
/* Base64 encode the signature value */
|
675 |
|
b64_sigret = xmlSecBase64Encode(sigret, sigret_size, 0);
|
|
643 |
b64_sigret = xmlSecBase64Encode(sigret, siglen, 0);
|
676 |
644 |
/* escape b64_sigret */
|
677 |
645 |
e_b64_sigret = lasso_xmlURIEscapeStr((xmlChar*)b64_sigret, NULL);
|
678 |
646 |
|
... | ... | |
701 |
669 |
lasso_release(sigret);
|
702 |
670 |
lasso_release_xml_string(b64_sigret);
|
703 |
671 |
lasso_release_xml_string(e_b64_sigret);
|
704 |
|
|
|
672 |
if (evp_md_ctx) {
|
|
673 |
EVP_MD_CTX_free(evp_md_ctx);
|
|
674 |
evp_md_ctx = NULL;
|
|
675 |
}
|
|
676 |
if (hmac_pkey) {
|
|
677 |
EVP_PKEY_free(hmac_pkey);
|
|
678 |
hmac_pkey = NULL;
|
|
679 |
pkey = NULL;
|
|
680 |
}
|
705 |
681 |
return s_new_query;
|
706 |
682 |
}
|
707 |
683 |
|
... | ... | |
728 |
704 |
|
729 |
705 |
static lasso_error_t
|
730 |
706 |
lasso_query_verify_helper(const char *signed_content, const char *b64_signature, const char *algorithm,
|
731 |
|
const xmlSecKey *key)
|
|
707 |
xmlSecKey *key)
|
732 |
708 |
{
|
733 |
|
RSA *rsa = NULL;
|
734 |
|
DSA *dsa = NULL;
|
735 |
709 |
char *digest = NULL;
|
736 |
|
xmlSecByte *signature = NULL;
|
737 |
|
int key_size = 0;
|
|
710 |
xmlSecByte signature[1024] = {0};
|
|
711 |
xmlSecSize signature_len = 0;
|
738 |
712 |
unsigned char *hmac_key = NULL;
|
739 |
713 |
size_t hmac_key_length = 0;
|
740 |
714 |
const EVP_MD *md = NULL;
|
741 |
715 |
lasso_error_t rc = 0;
|
742 |
716 |
LassoSignatureMethod method = LASSO_SIGNATURE_METHOD_NONE;
|
743 |
|
size_t digest_size = 1;
|
744 |
|
int type = -1;
|
|
717 |
EVP_PKEY *hmac_pkey = NULL;
|
|
718 |
unsigned char *new_signature = NULL;
|
|
719 |
EVP_MD_CTX *evp_md_ctx = NULL;
|
745 |
720 |
|
746 |
721 |
if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha1)) {
|
747 |
722 |
goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId,
|
748 |
723 |
LASSO_DS_ERROR_INVALID_SIGALG)
|
749 |
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value);
|
750 |
|
key_size = RSA_size(rsa);
|
751 |
724 |
method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
752 |
|
digest_size = SHA_DIGEST_LENGTH;
|
753 |
|
type = NID_sha1;
|
754 |
725 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefDsaSha1)) {
|
755 |
726 |
goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataDsaId, LASSO_DS_ERROR_INVALID_SIGALG);
|
756 |
|
dsa = xmlSecOpenSSLKeyDataDsaGetDsa(key->value);
|
757 |
|
key_size = DSA_size(dsa);
|
758 |
727 |
method = LASSO_SIGNATURE_METHOD_DSA_SHA1;
|
759 |
|
digest_size = SHA_DIGEST_LENGTH;
|
760 |
|
type = NID_sha1;
|
761 |
728 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha256)) {
|
762 |
729 |
goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId,
|
763 |
730 |
LASSO_DS_ERROR_INVALID_SIGALG)
|
764 |
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value);
|
765 |
|
key_size = RSA_size(rsa);
|
766 |
731 |
method = LASSO_SIGNATURE_METHOD_RSA_SHA256;
|
767 |
|
digest_size = SHA256_DIGEST_LENGTH;
|
768 |
|
type = NID_sha256;
|
769 |
732 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha384)) {
|
770 |
733 |
goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId,
|
771 |
734 |
LASSO_DS_ERROR_INVALID_SIGALG)
|
772 |
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value);
|
773 |
|
key_size = RSA_size(rsa);
|
774 |
735 |
method = LASSO_SIGNATURE_METHOD_RSA_SHA384;
|
775 |
|
digest_size = SHA384_DIGEST_LENGTH;
|
776 |
|
type = NID_sha384;
|
777 |
736 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha512)) {
|
778 |
737 |
goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId,
|
779 |
738 |
LASSO_DS_ERROR_INVALID_SIGALG)
|
780 |
|
rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value);
|
781 |
|
key_size = RSA_size(rsa);
|
782 |
739 |
method = LASSO_SIGNATURE_METHOD_RSA_SHA512;
|
783 |
|
digest_size = SHA512_DIGEST_LENGTH;
|
784 |
|
type = NID_sha512;
|
785 |
740 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha1)) {
|
786 |
741 |
lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length));
|
787 |
|
md = EVP_sha1();
|
788 |
|
key_size = EVP_MD_size(md);
|
789 |
742 |
method = LASSO_SIGNATURE_METHOD_HMAC_SHA1;
|
790 |
743 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha256)) {
|
791 |
744 |
lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length));
|
792 |
|
md = EVP_sha256();
|
793 |
|
key_size = EVP_MD_size(md);
|
794 |
745 |
method = LASSO_SIGNATURE_METHOD_HMAC_SHA256;
|
795 |
746 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha384)) {
|
796 |
747 |
lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length));
|
797 |
|
md = EVP_sha384();
|
798 |
|
key_size = EVP_MD_size(md);
|
799 |
748 |
method = LASSO_SIGNATURE_METHOD_HMAC_SHA384;
|
800 |
749 |
} else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha512)) {
|
801 |
750 |
lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length));
|
802 |
|
md = EVP_sha512();
|
803 |
|
key_size = EVP_MD_size(md);
|
804 |
751 |
method = LASSO_SIGNATURE_METHOD_HMAC_SHA512;
|
805 |
752 |
} else {
|
806 |
753 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGALG);
|
807 |
754 |
}
|
808 |
755 |
|
809 |
|
/* is the signature algo allowed */
|
810 |
|
goto_cleanup_if_fail_with_rc(
|
811 |
|
lasso_allowed_signature_method(method),
|
812 |
|
LASSO_DS_ERROR_INVALID_SIGALG);
|
813 |
|
|
814 |
|
/* decode signature */
|
815 |
|
signature = g_malloc(key_size+1);
|
816 |
|
goto_cleanup_if_fail_with_rc(
|
817 |
|
xmlSecBase64Decode((xmlChar*)b64_signature, signature, key_size+1) != 0,
|
818 |
|
LASSO_DS_ERROR_INVALID_SIGNATURE);
|
819 |
|
/* digest */
|
|
756 |
/* define the digest algorithm */
|
820 |
757 |
switch (method) {
|
821 |
758 |
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
822 |
759 |
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
823 |
|
digest = lasso_sha1(signed_content);
|
|
760 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
|
761 |
md = EVP_sha1();
|
824 |
762 |
break;
|
825 |
763 |
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
826 |
|
digest = lasso_sha256(signed_content);
|
|
764 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
|
765 |
md = EVP_sha256();
|
827 |
766 |
break;
|
828 |
767 |
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
829 |
|
digest = lasso_sha384(signed_content);
|
|
768 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
|
769 |
md = EVP_sha384();
|
830 |
770 |
break;
|
831 |
771 |
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
832 |
|
digest = lasso_sha512(signed_content);
|
833 |
|
break;
|
834 |
|
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
835 |
|
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
836 |
|
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
837 |
772 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA512:
|
|
773 |
md = EVP_sha512();
|
838 |
774 |
break;
|
839 |
|
default:
|
|
775 |
case LASSO_SIGNATURE_METHOD_NONE:
|
|
776 |
case LASSO_SIGNATURE_METHOD_LAST:
|
840 |
777 |
g_assert_not_reached();
|
841 |
778 |
}
|
|
779 |
|
|
780 |
/* is the signature algo allowed */
|
|
781 |
goto_cleanup_if_fail_with_rc(
|
|
782 |
lasso_allowed_signature_method(method),
|
|
783 |
LASSO_DS_ERROR_INVALID_SIGALG);
|
|
784 |
|
|
785 |
/* decode signature */
|
|
786 |
goto_cleanup_if_fail_with_rc(
|
|
787 |
xmlSecBase64Decode_ex((xmlChar*)b64_signature, signature, 1024, &signature_len) == 0,
|
|
788 |
LASSO_DS_ERROR_INVALID_SIGNATURE);
|
842 |
789 |
/* verify signature */
|
|
790 |
evp_md_ctx = EVP_MD_CTX_create();
|
|
791 |
|
843 |
792 |
switch (method) {
|
844 |
793 |
case LASSO_SIGNATURE_METHOD_RSA_SHA1:
|
845 |
794 |
case LASSO_SIGNATURE_METHOD_RSA_SHA256:
|
846 |
795 |
case LASSO_SIGNATURE_METHOD_RSA_SHA384:
|
847 |
796 |
case LASSO_SIGNATURE_METHOD_RSA_SHA512:
|
848 |
|
goto_cleanup_if_fail_with_rc(
|
849 |
|
RSA_verify(
|
850 |
|
type,
|
851 |
|
(unsigned char*)digest,
|
852 |
|
digest_size,
|
853 |
|
signature,
|
854 |
|
key_size, rsa) == 1,
|
855 |
|
LASSO_DS_ERROR_INVALID_SIGNATURE);
|
856 |
|
break;
|
857 |
797 |
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
|
858 |
|
goto_cleanup_if_fail_with_rc(
|
859 |
|
DSA_verify(
|
860 |
|
type,
|
861 |
|
(unsigned char*)digest,
|
862 |
|
digest_size,
|
863 |
|
signature,
|
864 |
|
key_size, dsa) == 1,
|
865 |
|
LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
798 |
{
|
|
799 |
xmlSecKeyData *key_data = xmlSecKeyGetValue(key);
|
|
800 |
if (! key_data) {
|
|
801 |
message(G_LOG_LEVEL_CRITICAL, "Failed to get KeyData");
|
|
802 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
803 |
}
|
|
804 |
EVP_PKEY *pkey = xmlSecOpenSSLEvpKeyDataGetEvp(key_data);
|
|
805 |
if (! pkey) {
|
|
806 |
message(G_LOG_LEVEL_CRITICAL, "Failed to get assymetric key");
|
|
807 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
808 |
}
|
|
809 |
if (1 != EVP_DigestVerifyInit(evp_md_ctx, NULL, md, NULL, pkey)) {
|
|
810 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestVerifyInit failed");
|
|
811 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
812 |
}
|
|
813 |
if (1 != EVP_DigestVerifyUpdate(evp_md_ctx, signed_content, strlen(signed_content))) {
|
|
814 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestVerifyUpdate failed");
|
|
815 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
816 |
}
|
|
817 |
if(1 != EVP_DigestVerifyFinal(evp_md_ctx, signature, signature_len)) {
|
|
818 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
819 |
}
|
|
820 |
}
|
866 |
821 |
break;
|
867 |
822 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA1:
|
868 |
823 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA256:
|
869 |
824 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA384:
|
870 |
825 |
case LASSO_SIGNATURE_METHOD_HMAC_SHA512:
|
871 |
|
digest = g_malloc(key_size);
|
872 |
|
HMAC(md, hmac_key, hmac_key_length, (unsigned char*)signed_content,
|
873 |
|
strlen(signed_content), (unsigned char*)digest, NULL);
|
|
826 |
{
|
|
827 |
unsigned char *hmac_key;
|
|
828 |
size_t hmac_key_length;
|
|
829 |
size_t new_signature_len;
|
|
830 |
|
|
831 |
if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key,
|
|
832 |
&hmac_key_length))) {
|
|
833 |
message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc));
|
|
834 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
835 |
}
|
|
836 |
g_assert(hmac_key);
|
|
837 |
hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, hmac_key, (int)hmac_key_length);
|
|
838 |
if (! hmac_key) {
|
|
839 |
message(G_LOG_LEVEL_CRITICAL, "EVP_PKEY_new_mac_key failed");
|
|
840 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
841 |
}
|
874 |
842 |
|
875 |
|
goto_cleanup_if_fail_with_rc(lasso_crypto_memequal(digest, signature,
|
876 |
|
key_size),
|
877 |
|
LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
843 |
if (EVP_DigestSignInit(evp_md_ctx, NULL, md, NULL, hmac_pkey) != 1) {
|
|
844 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSignInit failed");
|
|
845 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
846 |
}
|
|
847 |
if (EVP_DigestSign(evp_md_ctx, NULL, &new_signature_len, (unsigned char*)signed_content, strlen(signed_content)) != 1) {
|
|
848 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed");
|
|
849 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
850 |
}
|
|
851 |
if (new_signature_len != signature_len) {
|
|
852 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
853 |
}
|
|
854 |
new_signature = g_malloc(new_signature_len);
|
|
855 |
if (EVP_DigestSign(evp_md_ctx, new_signature, &new_signature_len, (unsigned char*)signed_content, strlen(signed_content)) != 1) {
|
|
856 |
message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed");
|
|
857 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
858 |
}
|
|
859 |
if (CRYPTO_memcmp(signature, new_signature, signature_len) != 0) {
|
|
860 |
goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE);
|
|
861 |
}
|
|
862 |
}
|
878 |
863 |
break;
|
879 |
864 |
case LASSO_SIGNATURE_METHOD_NONE:
|
880 |
865 |
case LASSO_SIGNATURE_METHOD_LAST:
|
... | ... | |
882 |
867 |
}
|
883 |
868 |
cleanup:
|
884 |
869 |
lasso_release_string(digest);
|
885 |
|
lasso_release_string(signature);
|
|
870 |
lasso_release_string(new_signature);
|
|
871 |
if (evp_md_ctx) {
|
|
872 |
EVP_MD_CTX_free(evp_md_ctx);
|
|
873 |
evp_md_ctx = NULL;
|
|
874 |
}
|
|
875 |
if (hmac_pkey) {
|
|
876 |
EVP_PKEY_free(hmac_pkey);
|
|
877 |
hmac_pkey = NULL;
|
|
878 |
}
|
886 |
879 |
return rc;
|
887 |
880 |
|
888 |
881 |
}
|
... | ... | |
899 |
892 |
* a negative value if an error occurs during verification
|
900 |
893 |
**/
|
901 |
894 |
lasso_error_t
|
902 |
|
lasso_query_verify_signature(const char *query, const xmlSecKey *sender_public_key)
|
|
895 |
lasso_query_verify_signature(const char *query, xmlSecKey *sender_public_key)
|
903 |
896 |
{
|
904 |
897 |
gchar **str_split = NULL;
|
905 |
898 |
char *b64_signature = NULL;
|
... | ... | |
958 |
951 |
* Return value: 0 if signature is validated, an error code otherwise.
|
959 |
952 |
*/
|
960 |
953 |
int
|
961 |
|
lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key)
|
|
954 |
lasso_saml2_query_verify_signature(const char *query, xmlSecKey *sender_public_key)
|
962 |
955 |
{
|
963 |
956 |
char *b64_signature = NULL;
|
964 |
957 |
char *query_copy = NULL;
|
... | ... | |
1364 |
1357 |
}
|
1365 |
1358 |
|
1366 |
1359 |
unsigned char*
|
1367 |
|
lasso_inflate(unsigned char *input, size_t len)
|
|
1360 |
lasso_inflate(unsigned char *input, size_t len, size_t *outlen)
|
1368 |
1361 |
{
|
1369 |
1362 |
z_stream zstr;
|
1370 |
1363 |
unsigned char *output;
|
1371 |
1364 |
int z_err;
|
1372 |
1365 |
|
|
1366 |
*outlen = 0;
|
1373 |
1367 |
zstr.zalloc = NULL;
|
1374 |
1368 |
zstr.zfree = NULL;
|
1375 |
1369 |
zstr.opaque = NULL;
|
... | ... | |
1398 |
1392 |
}
|
1399 |
1393 |
output[zstr.total_out] = 0;
|
1400 |
1394 |
inflateEnd(&zstr);
|
|
1395 |
*outlen = zstr.total_out;
|
1401 |
1396 |
|
1402 |
1397 |
return output;
|
1403 |
1398 |
}
|
... | ... | |
1406 |
1401 |
gboolean
|
1407 |
1402 |
lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string)
|
1408 |
1403 |
{
|
1409 |
|
int len;
|
1410 |
|
xmlChar *b64_zre, *zre, *re;
|
1411 |
|
xmlDoc *doc;
|
1412 |
|
xmlNode *root;
|
1413 |
|
|
1414 |
|
b64_zre = (xmlChar*)xmlURIUnescapeString(deflate_string, 0, NULL);
|
1415 |
|
len = strlen((char*)b64_zre);
|
1416 |
|
zre = xmlMalloc(len*4);
|
1417 |
|
len = xmlSecBase64Decode(b64_zre, zre, len*4);
|
1418 |
|
xmlFree(b64_zre);
|
1419 |
|
if (len == -1) {
|
1420 |
|
message(G_LOG_LEVEL_CRITICAL, "Failed to base64-decode query");
|
1421 |
|
xmlFree(zre);
|
1422 |
|
return FALSE;
|
1423 |
|
}
|
|
1404 |
xmlChar *buffer= NULL;
|
|
1405 |
xmlSecSize buffer_len = 0;
|
|
1406 |
xmlChar *re = NULL;
|
|
1407 |
size_t re_len = 0;
|
|
1408 |
xmlDoc *doc = NULL;
|
|
1409 |
xmlNode *root = NULL;
|
|
1410 |
gboolean rc = TRUE;
|
1424 |
1411 |
|
1425 |
|
re = lasso_inflate(zre, len);
|
1426 |
|
xmlFree(zre);
|
|
1412 |
buffer = (xmlChar*)xmlURIUnescapeString(deflate_string, 0, NULL);
|
|
1413 |
goto_cleanup_if_fail_with_rc(xmlSecBase64DecodeInPlace(buffer, &buffer_len) == 0, FALSE);
|
1427 |
1414 |
|
1428 |
|
if (! re)
|
1429 |
|
return FALSE;
|
|
1415 |
re = lasso_inflate(buffer, buffer_len, &re_len);
|
|
1416 |
goto_cleanup_if_fail_with_rc_with_warning(re != NULL, FALSE);
|
1430 |
1417 |
|
1431 |
1418 |
doc = lasso_xml_parse_memory((char*)re, strlen((char*)re));
|
1432 |
|
lasso_release_string(re);
|
1433 |
1419 |
|
|
1420 |
goto_cleanup_if_fail_with_rc_with_warning(doc != NULL, FALSE);
|
1434 |
1421 |
root = xmlDocGetRootElement(doc);
|
1435 |
1422 |
lasso_node_init_from_xml(node, root);
|
1436 |
|
lasso_release_doc(doc);
|
1437 |
1423 |
|
1438 |
|
return TRUE;
|
|
1424 |
cleanup:
|
|
1425 |
lasso_release_xml_string(buffer);
|
|
1426 |
lasso_release_doc(doc);
|
|
1427 |
lasso_release_string(re);
|
|
1428 |
return rc;
|
1439 |
1429 |
}
|
1440 |
1430 |
|
1441 |
1431 |
char*
|
... | ... | |
1897 |
1887 |
lasso_xml_parse_message(const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out)
|
1898 |
1888 |
{
|
1899 |
1889 |
char *msg = NULL;
|
1900 |
|
gboolean b64 = FALSE;
|
|
1890 |
xmlSecSize msg_len = 0;
|
1901 |
1891 |
LassoMessageFormat rc = LASSO_MESSAGE_FORMAT_UNKNOWN;
|
1902 |
1892 |
xmlDoc *doc = NULL;
|
1903 |
1893 |
xmlNode *root = NULL;
|
1904 |
1894 |
gboolean any = constraint == LASSO_MESSAGE_FORMAT_UNKNOWN;
|
1905 |
1895 |
|
1906 |
|
msg = (char*)message;
|
|
1896 |
msg = g_strdup(message);
|
|
1897 |
msg_len = strlen(message);
|
1907 |
1898 |
|
1908 |
1899 |
/* BASE64 case */
|
1909 |
1900 |
if (any || constraint == LASSO_MESSAGE_FORMAT_BASE64) {
|
1910 |
1901 |
if (message[0] != 0 && is_base64(message)) {
|
1911 |
|
msg = g_malloc(strlen(message));
|
1912 |
|
rc = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)msg, strlen(message));
|
1913 |
|
if (rc >= 0) {
|
1914 |
|
b64 = TRUE;
|
|
1902 |
if (xmlSecBase64DecodeInPlace((xmlChar*)msg, &msg_len) == 0) {
|
|
1903 |
rc = LASSO_MESSAGE_FORMAT_BASE64;
|
1915 |
1904 |
} else {
|
1916 |
1905 |
lasso_release(msg);
|
1917 |
|
msg = (char*)message;
|
|
1906 |
msg = g_strdup(message);
|
|
1907 |
msg_len = strlen(message);
|
1918 |
1908 |
}
|
1919 |
1909 |
}
|
1920 |
1910 |
}
|
... | ... | |
1924 |
1914 |
constraint == LASSO_MESSAGE_FORMAT_XML ||
|
1925 |
1915 |
constraint == LASSO_MESSAGE_FORMAT_SOAP) {
|
1926 |
1916 |
if (strchr(msg, '<')) {
|
1927 |
|
doc = lasso_xml_parse_memory(msg, strlen(msg));
|
|
1917 |
doc = lasso_xml_parse_memory(msg, msg_len);
|
1928 |
1918 |
if (doc == NULL) {
|
1929 |
1919 |
rc = LASSO_MESSAGE_FORMAT_UNKNOWN;
|
1930 |
1920 |
goto cleanup;
|
1931 |
1921 |
}
|
1932 |
1922 |
root = xmlDocGetRootElement(doc);
|
|
1923 |
if (! root) {
|
|
1924 |
rc = LASSO_MESSAGE_FORMAT_ERROR;
|
|
1925 |
goto cleanup;
|
|
1926 |
}
|
1933 |
1927 |
|
1934 |
1928 |
if (any || constraint == LASSO_MESSAGE_FORMAT_SOAP) {
|
1935 |
1929 |
gboolean is_soap = FALSE;
|
... | ... | |
1938 |
1932 |
if (is_soap) {
|
1939 |
1933 |
root = lasso_xml_get_soap_content(root);
|
1940 |
1934 |
}
|
1941 |
|
if (! root) {
|
1942 |
|
rc = LASSO_MESSAGE_FORMAT_ERROR;
|
1943 |
|
goto cleanup;
|
1944 |
|
}
|
1945 |
1935 |
if (is_soap) {
|
1946 |
1936 |
rc = LASSO_MESSAGE_FORMAT_SOAP;
|
1947 |
1937 |
goto cleanup;
|
1948 |
1938 |
}
|
1949 |
|
if (b64) {
|
1950 |
|
lasso_release(msg);
|
1951 |
|
rc = LASSO_MESSAGE_FORMAT_BASE64;
|
|
1939 |
if (rc == LASSO_MESSAGE_FORMAT_BASE64) {
|
1952 |
1940 |
goto cleanup;
|
1953 |
1941 |
}
|
1954 |
1942 |
rc = LASSO_MESSAGE_FORMAT_XML;
|
1955 |
|
goto cleanup;
|
1956 |
1943 |
}
|
1957 |
1944 |
}
|
1958 |
1945 |
}
|
1959 |
1946 |
|
1960 |
1947 |
cleanup:
|
|
1948 |
lasso_release(msg);
|
1961 |
1949 |
if (doc_out) {
|
1962 |
1950 |
*doc_out = doc;
|
1963 |
1951 |
if (root_out) {
|
... | ... | |
1965 |
1953 |
}
|
1966 |
1954 |
} else {
|
1967 |
1955 |
lasso_release_doc(doc);
|
1968 |
|
lasso_release_xml_node(root);
|
1969 |
1956 |
}
|
1970 |
1957 |
return rc;
|
1971 |
1958 |
}
|
... | ... | |
2529 |
2516 |
*buffer = g_malloc0(len);
|
2530 |
2517 |
|
2531 |
2518 |
xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
|
2532 |
|
ret = xmlSecBase64Decode(BAD_CAST from, BAD_CAST *buffer, len);
|
2533 |
|
xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
|
2534 |
|
if (ret <= 0) {
|
|
2519 |
ret = xmlSecBase64Decode_ex(BAD_CAST from, BAD_CAST *buffer, len, (xmlSecSize*)buffer_len);
|
|
2520 |
if (ret != 0) {
|
2535 |
2521 |
lasso_release_string(*buffer);
|
2536 |
2522 |
return FALSE;
|
2537 |
2523 |
}
|
2538 |
|
*buffer_len = ret;
|
2539 |
2524 |
return TRUE;
|
2540 |
2525 |
}
|
2541 |
2526 |
|
... | ... | |
2559 |
2544 |
int ri;
|
2560 |
2545 |
|
2561 |
2546 |
if (list == NULL)
|
2562 |
|
list = "";
|
|
2547 |
list = (xmlChar*)"";
|
2563 |
2548 |
|
2564 |
2549 |
for (fp = from; *fp; fp++) {
|
2565 |
|
if (isalnum(*fp) || strchr("._~-", *fp) || strchr(list, *fp))
|
|
2550 |
if (isalnum(*fp) || strchr("._~-", *fp) || strchr((char*)list, *fp))
|
2566 |
2551 |
len++;
|
2567 |
2552 |
else
|
2568 |
2553 |
len += 3;
|
... | ... | |
2572 |
2557 |
ri = 0;
|
2573 |
2558 |
|
2574 |
2559 |
for (fp = from; *fp; fp++) {
|
2575 |
|
if (isalnum(*fp) || strchr("._~-", *fp) || strchr(list, *fp)) {
|
|
2560 |
if (isalnum(*fp) || strchr("._~-", *fp) || strchr((char*)list, *fp)) {
|
2576 |
2561 |
result[ri++] = *fp;
|
2577 |
2562 |
} else {
|
2578 |
2563 |
int msb = (*fp & 0xf0) >> 4;
|
... | ... | |
3168 |
3153 |
char *enc = NULL;
|
3169 |
3154 |
char *message = NULL;
|
3170 |
3155 |
char *saml_message = NULL;
|
|
3156 |
size_t saml_message_len = 0;
|
3171 |
3157 |
char *decoded_message = NULL;
|
3172 |
3158 |
xmlChar *field = NULL;
|
3173 |
3159 |
char *t = NULL;
|
... | ... | |
3208 |
3194 |
goto cleanup;
|
3209 |
3195 |
}
|
3210 |
3196 |
/* rc contains the length of the result */
|
3211 |
|
saml_message = (char*)lasso_inflate((unsigned char*) decoded_message, rc);
|
|
3197 |
saml_message = (char*)lasso_inflate((unsigned char*) decoded_message, rc, &saml_message_len);
|
3212 |
3198 |
cleanup:
|
3213 |
3199 |
if (decoded_message) {
|
3214 |
3200 |
lasso_release(decoded_message);
|
3215 |
|
-
|