1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*
21 * XSEC
22 *
23 * SimpleHMAC := An application to generate an XML document (via Xerces) and sign it
24 *
25 * Author(s): Berin Lautenbach
26 *
27 * $ID$
28 *
29 * $LOG$
30 *
31 */
32
33 #include "IOStreamOutputter.hpp"
34
35 // Xerces
36
37 #include <xercesc/util/PlatformUtils.hpp>
38
39 // XML-Security-C (XSEC)
40
41 #include <xsec/framework/XSECProvider.hpp>
42 #include <xsec/dsig/DSIGReference.hpp>
43 #include <xsec/framework/XSECException.hpp>
44 #include <xsec/utils/XSECPlatformUtils.hpp>
45
46 #include "../utils/XSECDOMUtils.hpp"
47
48 // Xalan
49
50 #ifdef XSEC_HAVE_XALAN
51 #include <xalanc/XalanTransformer/XalanTransformer.hpp>
52 // If this isn't defined, we're on Xalan 1.12+ and require modern C++
53 #ifndef XALAN_USING_XALAN
54 # define XALAN_USING_XALAN(NAME) using xalanc :: NAME;
55 #endif
XALAN_USING_XALAN(XalanTransformer)56 XALAN_USING_XALAN(XalanTransformer)
57 #endif
58
59 XERCES_CPP_NAMESPACE_USE
60
61 DOMDocument *createLetter(DOMImplementation *impl) {
62
63 DOMDocument *doc = impl->createDocument(
64 0,
65 MAKE_UNICODE_STRING("Letter"),
66 NULL);
67
68 DOMElement *rootElem = doc->getDocumentElement();
69
70 // Add the ToAddress
71
72 DOMElement *addressElem = doc->createElement(MAKE_UNICODE_STRING("ToAddress"));
73 rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
74 rootElem->appendChild(addressElem);
75 addressElem->appendChild(doc->createTextNode(
76 MAKE_UNICODE_STRING("The address of the Recipient")));
77
78 // Add the FromAddress
79 addressElem = doc->createElement(MAKE_UNICODE_STRING("FromAddress"));
80 rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
81 rootElem->appendChild(addressElem);
82 addressElem->appendChild(doc->createTextNode(
83 MAKE_UNICODE_STRING("The address of the Sender")));
84
85 // Add some text
86 DOMElement *textElem = doc->createElement(MAKE_UNICODE_STRING("Text"));
87 rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
88 rootElem->appendChild(textElem);
89 textElem->appendChild(doc->createTextNode(
90 MAKE_UNICODE_STRING("\nTo whom it may concern\n\n...\n")));
91
92 return doc;
93
94 }
95
main(int argc,char ** argv)96 int main (int argc, char **argv) {
97
98 try {
99 XMLPlatformUtils::Initialize();
100 #ifdef XSEC_HAVE_XALAN
101 XalanTransformer::initialize();
102 #endif
103 XSECPlatformUtils::Initialise();
104 }
105 catch (const XMLException &e) {
106
107 cerr << "Error during initialisation of Xerces" << endl;
108 cerr << "Error Message = : "
109 << e.getMessage() << endl;
110
111 }
112
113 // Create a blank Document
114
115 DOMImplementation *impl =
116 DOMImplementationRegistry::getDOMImplementation(MAKE_UNICODE_STRING("Core"));
117
118 // Create a letter
119 DOMDocument *doc = createLetter(impl);
120 DOMElement *rootElem = doc->getDocumentElement();
121
122 // The signature
123
124 XSECProvider prov;
125 DSIGSignature *sig;
126 DOMElement *sigNode;
127
128 try {
129
130 // Create a signature object
131
132 sig = prov.newSignature();
133 sig->setDSIGNSPrefix(MAKE_UNICODE_STRING("ds"));
134
135 // Use it to create a blank signature DOM structure from the doc
136
137 sigNode = sig->createBlankSignature(doc,
138 DSIGConstants::s_unicodeStrURIC14N_NOC,
139 DSIGConstants::s_unicodeStrURIHMAC_SHA1);
140
141 // Inser the signature DOM nodes into the doc
142
143 rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
144 rootElem->appendChild(sigNode);
145 rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
146
147 // Create an envelope reference for the text to be signed
148 DSIGReference * ref = sig->createReference(MAKE_UNICODE_STRING(""), DSIGConstants::s_unicodeStrURISHA1);
149 ref->appendEnvelopedSignatureTransform();
150
151 // Set the HMAC Key to be the string "secret"
152
153 XSECCryptoKeyHMAC* hmacKey = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
154 hmacKey->setKey((unsigned char *) "secret", (unsigned int) strlen("secret"));
155 sig->setSigningKey(hmacKey);
156
157 // Add a KeyInfo element
158 sig->appendKeyName(MAKE_UNICODE_STRING("The secret key is \"secret\""));
159
160 // Sign
161
162 sig->sign();
163 }
164
165 catch (const XSECException &e)
166 {
167 cerr << "An error occurred during a signature load\n Message: "
168 << e.getMsg() << endl;
169 exit(1);
170
171 }
172
173 // Output
174
175 docSetup(doc);
176 cout << doc;
177
178 return 0;
179
180 }
181