~ubuntu-branches/ubuntu/hardy/lasso/hardy

« back to all changes in this revision

Viewing changes to lasso/xml/tools.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia
  • Date: 2007-07-31 21:35:26 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070731213526-oc6jw5mprcd5tjyy
Tags: 2.0.0-1ubuntu1
* Merge from debian unstable. Remaining changes:
  + debian/control:
    - Modify Maintainer value to match DebianMaintainerField spec.
* debian/rules:
  + Add CC=gcc-4.2 to the configure call else configure won't find jni.h
    from libgcj8-dev.
* configure{,.ac}:
  + Add missing quotes around the value for PHP[45]_LIBS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: tools.c,v 1.77 2005/11/20 15:38:19 fpeters Exp $ 
 
1
/* $Id: tools.c,v 1.97 2007/01/07 12:17:30 fpeters Exp $ 
2
2
 *
3
3
 * Lasso - A free implementation of the Liberty Alliance specifications.
4
4
 *
36
36
#include <xmlsec/templates.h>
37
37
#include <xmlsec/xmldsig.h>
38
38
#include <xmlsec/xmltree.h>
 
39
#include <xmlsec/errors.h>
 
40
#include <xmlsec/openssl/x509.h>
 
41
#include <xmlsec/openssl/crypto.h>
39
42
 
40
43
#include <zlib.h>
41
44
 
42
45
#include <lasso/xml/xml.h>
 
46
#include <lasso/xml/xml_enc.h>
 
47
#include <lasso/xml/saml-2.0/saml2_assertion.h>
 
48
 
 
49
LassoNode* lasso_assertion_encrypt(LassoSaml2Assertion *assertion);
43
50
 
44
51
/**
45
52
 * lasso_build_random_sequence:
142
149
        bio = BIO_new_file(pem_file, "rb");
143
150
        if (bio == NULL) {
144
151
                message(G_LOG_LEVEL_CRITICAL, "Failed to open %s pem file", pem_file);
145
 
                return -1;
 
152
                return LASSO_PEM_FILE_TYPE_UNKNOWN;
146
153
        }
147
154
 
148
155
        pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
150
157
                type = LASSO_PEM_FILE_TYPE_PUB_KEY;
151
158
                EVP_PKEY_free(pkey);
152
159
        } else {
153
 
                BIO_reset(bio);
154
 
                pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
155
 
                if (pkey != NULL) {
156
 
                        type = LASSO_PEM_FILE_TYPE_PRIVATE_KEY;
157
 
                        EVP_PKEY_free(pkey);
158
 
                } else {
159
 
                        BIO_reset(bio);
160
 
                        cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
161
 
                        if (cert != NULL) {
162
 
                                type = LASSO_PEM_FILE_TYPE_CERT;
163
 
                                X509_free(cert);
 
160
                if (BIO_reset(bio) == 0) {
 
161
                        pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
 
162
                        if (pkey != NULL) {
 
163
                                type = LASSO_PEM_FILE_TYPE_PRIVATE_KEY;
 
164
                                EVP_PKEY_free(pkey);
 
165
                        } else {
 
166
                                if (BIO_reset(bio) == 0) {
 
167
                                        cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
 
168
                                        if (cert != NULL) {
 
169
                                                type = LASSO_PEM_FILE_TYPE_CERT;
 
170
                                                X509_free(cert);
 
171
                                        }
 
172
                                }
164
173
                        }
165
174
                }
166
175
        }
362
371
                /* sign digest message */
363
372
                status = RSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret, &siglen, rsa);
364
373
                RSA_free(rsa);
365
 
        }
366
 
        else if (sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
 
374
        } else if (sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
367
375
                dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL);
368
376
                if (dsa == NULL) {
369
377
                        goto done;
372
380
                status = DSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret, &siglen, dsa);
373
381
                DSA_free(dsa);
374
382
        }
 
383
 
375
384
        if (status == 0) {
376
385
                goto done;
377
386
        }
402
411
        return s_new_query;
403
412
}
404
413
 
 
414
LassoNode*
 
415
lasso_assertion_encrypt(LassoSaml2Assertion *assertion)
 
416
{
 
417
        LassoNode *encrypted_element = NULL;
 
418
        gchar *b64_value;
 
419
        xmlSecByte *value;
 
420
        int length;
 
421
        int rc;
 
422
        xmlSecKey *encryption_public_key = NULL;
 
423
        int i;
 
424
        xmlSecKeyDataFormat key_formats[] = {
 
425
                xmlSecKeyDataFormatDer,
 
426
                xmlSecKeyDataFormatCertDer,
 
427
                xmlSecKeyDataFormatPkcs8Der,
 
428
                xmlSecKeyDataFormatCertPem,
 
429
                xmlSecKeyDataFormatPkcs8Pem,
 
430
                xmlSecKeyDataFormatPem,
 
431
                xmlSecKeyDataFormatBinary,
 
432
                0
 
433
        };
 
434
 
 
435
        if (assertion->encryption_activated == FALSE ||
 
436
                        assertion->encryption_public_key_str == NULL) {
 
437
                return NULL;
 
438
        }
 
439
 
 
440
        b64_value = g_strdup(assertion->encryption_public_key_str);
 
441
        length = strlen(b64_value);
 
442
        value = g_malloc(length*4); /* enough place for decoding */
 
443
        rc = xmlSecBase64Decode((xmlChar*)b64_value, value, length);
 
444
        if (rc < 0) {
 
445
                /* bad base-64 */
 
446
                g_free(value);
 
447
                g_free(b64_value);
 
448
                return NULL;
 
449
        }
 
450
 
 
451
        xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
 
452
        for (i = 0; key_formats[i] && encryption_public_key == NULL; i++) {
 
453
                encryption_public_key = xmlSecCryptoAppKeyLoadMemory(value, rc,
 
454
                                key_formats[i], NULL, NULL, NULL);
 
455
        }
 
456
        xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
 
457
 
 
458
        /* Finally encrypt the assertion */
 
459
        encrypted_element = LASSO_NODE(lasso_node_encrypt(LASSO_NODE(assertion),
 
460
                encryption_public_key, assertion->encryption_sym_key_type));
 
461
 
 
462
        g_free(b64_value);
 
463
        g_free(value);  
 
464
 
 
465
        return encrypted_element;
 
466
}
 
467
 
 
468
 
405
469
/**
406
470
 * lasso_query_verify_signature:
407
471
 * @query: a query (an url-encoded message)
609
673
        xmlDoc *doc;
610
674
        xmlNode *sign_tmpl, *old_parent;
611
675
        xmlSecDSigCtx *dsig_ctx;
 
676
        xmlAttr *id_attr = NULL;
612
677
 
613
678
        sign_tmpl = NULL;
614
679
        for (sign_tmpl = xmlnode->children; sign_tmpl; sign_tmpl = sign_tmpl->next) {
625
690
        xmlnode->parent = NULL;
626
691
        xmlDocSetRootElement(doc, xmlnode);
627
692
        xmlSetTreeDoc(sign_tmpl, doc);
628
 
        if (id_attr_name) {
629
 
                xmlAttr *id_attr = xmlHasProp(xmlnode, (xmlChar*)id_attr_name);
630
 
                if (id_value) {
631
 
                        xmlAddID(NULL, doc, (xmlChar*)id_value, id_attr);
632
 
                }
 
693
        if (id_attr_name && id_value) {
 
694
                id_attr = xmlHasProp(xmlnode, (xmlChar*)id_attr_name);
 
695
                xmlAddID(NULL, doc, (xmlChar*)id_value, id_attr);
633
696
        }
634
697
 
635
698
        dsig_ctx = xmlSecDSigCtxCreate(NULL);
653
716
        }
654
717
        xmlSecDSigCtxDestroy(dsig_ctx);
655
718
        xmlUnlinkNode(xmlnode);
 
719
        xmlRemoveID(doc, id_attr);
 
720
 
656
721
        xmlnode->parent = old_parent;
 
722
#if 0
 
723
        /* memory leak since we don't free doc but it causes some little memory
 
724
         * corruption; probably caused by the direct manipulation of xmlnode
 
725
         * parent attribute. */
657
726
        xmlFreeDoc(doc);
 
727
#endif
658
728
 
659
729
        return 0;
660
730
}
663
733
lasso_node_build_deflated_query(LassoNode *node)
664
734
{
665
735
        /* actually deflated and b64'ed and url-escaped */
666
 
        xmlNode *message;
 
736
        xmlNode *xmlnode;
667
737
        xmlOutputBufferPtr buf;
668
738
        xmlCharEncodingHandlerPtr handler = NULL;
669
739
        xmlChar *buffer;
670
 
        xmlChar *ret, *orig_ret, *b64_ret;
671
 
        z_stream zstr;
672
 
        int z_err;
673
 
        int buf_size;
 
740
        xmlChar *ret, *b64_ret;
674
741
        char *rret;
675
 
 
676
 
        message = lasso_node_get_xmlNode(node, FALSE);
677
 
 
 
742
        unsigned long in_len;
 
743
        int rc;
 
744
        z_stream stream;
 
745
 
 
746
        xmlnode = lasso_node_get_xmlNode(node, FALSE);
 
747
        
678
748
        handler = xmlFindCharEncodingHandler("utf-8");
679
749
        buf = xmlAllocOutputBuffer(handler);
680
 
        xmlNodeDumpOutput(buf, NULL, message, 0, 0, "utf-8");
 
750
        xmlNodeDumpOutput(buf, NULL, xmlnode, 0, 0, "utf-8");
681
751
        xmlOutputBufferFlush(buf);
682
752
        buffer = buf->conv ? buf->conv->content : buf->buffer->content;
683
753
 
684
 
 
685
 
        zstr.zalloc = NULL;
686
 
        zstr.zfree = NULL;
687
 
        zstr.opaque = NULL;
688
 
 
689
 
        zstr.avail_in = strlen((char*)buffer);
690
 
        buf_size = zstr.avail_in*2;
691
 
        ret = orig_ret = g_malloc(buf_size);
 
754
        xmlFreeNode(xmlnode);
 
755
        xmlnode = NULL;
 
756
 
 
757
        in_len = strlen((char*)buffer);
 
758
        ret = g_malloc(in_len * 2);
692
759
                /* deflating should never increase the required size but we are
693
760
                 * more conservative than that.  Twice the size should be
694
761
                 * enough. */
695
 
        zstr.next_in = buffer;
696
 
        zstr.total_in = 0;
697
 
        zstr.next_out = ret;
698
 
 
699
 
        z_err = deflateInit(&zstr, 6);
700
 
        if (z_err != Z_OK) {
701
 
                message(G_LOG_LEVEL_CRITICAL, "Failed to deflateInit");
702
 
                return NULL;
 
762
 
 
763
        stream.next_in = buffer;
 
764
        stream.avail_in = in_len;
 
765
        stream.next_out = ret;
 
766
        stream.avail_out = in_len * 2;
 
767
 
 
768
        stream.zalloc = NULL;
 
769
        stream.zfree = NULL;
 
770
        stream.opaque = NULL;
 
771
 
 
772
        /* -MAX_WBITS to disable zib headers */
 
773
        rc = deflateInit2(&stream, Z_DEFAULT_COMPRESSION,
 
774
                Z_DEFLATED, -MAX_WBITS, 5, 0);
 
775
        if (rc == Z_OK) {
 
776
                rc = deflate(&stream, Z_FINISH);
 
777
                if (rc != Z_STREAM_END) {
 
778
                        deflateEnd(&stream);
 
779
                        if (rc == Z_OK) {
 
780
                                rc = Z_BUF_ERROR;
 
781
                        }
 
782
                } else {
 
783
                        rc = deflateEnd(&stream);
 
784
                }
703
785
        }
704
 
        do {
705
 
                z_err = deflate(&zstr, Z_FINISH);
706
 
                if (z_err == Z_OK) {
707
 
                        buf_size *= 2;
708
 
                        ret = g_realloc(ret, buf_size);
709
 
                        zstr.next_out = (xmlChar*) orig_ret-zstr.next_out+ret;
710
 
                        orig_ret = ret;
711
 
                }
712
 
        } while (z_err == Z_OK);
713
 
        if (z_err != Z_STREAM_END) {
 
786
        if (rc != Z_OK) {
 
787
                g_free(ret);
714
788
                message(G_LOG_LEVEL_CRITICAL, "Failed to deflate");
715
789
                return NULL;
716
790
        }
717
791
 
718
 
        b64_ret = xmlSecBase64Encode(ret, zstr.total_out, 0);
 
792
        b64_ret = xmlSecBase64Encode(ret, stream.total_out, 0);
719
793
        xmlOutputBufferClose(buf);
720
 
        free(ret);
 
794
        g_free(ret);
721
795
 
722
796
        ret = xmlURIEscapeStr(b64_ret, NULL);
723
797
        rret = g_strdup((char*)ret);
755
829
        zstr.total_out = 0;
756
830
        zstr.next_out = re;
757
831
 
758
 
        z_err = inflateInit(&zstr);
 
832
        z_err = inflateInit2(&zstr, -MAX_WBITS);
759
833
        if (z_err != Z_OK) {
760
834
                message(G_LOG_LEVEL_CRITICAL, "Failed to inflateInit");
761
835
                xmlFree(zre);
784
858
        return TRUE;
785
859
}
786
860
 
 
861
char*
 
862
lasso_concat_url_query(char *url, char *query)
 
863
{
 
864
        if (strchr(url, '?')) {
 
865
                return g_strdup_printf("%s&%s", url, query);
 
866
        } else {
 
867
                return g_strdup_printf("%s?%s", url, query);
 
868
        }
 
869
}
 
870