void DSIGTransformXPath::deleteNamespace(const char * prefix) { DOMElement *x; x = static_cast <DOMElement *> (mp_xpathNode); // if (x == NULL) { // // throw XSECException(XSECException::TransformError, // "Found a non ELEMENT node as the XPath node in DSIGTransformXPath"); // } x->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, MAKE_UNICODE_STRING(prefix)); }
static auto_ptr<DSIGKeyInfoX509> SAMLFindKey(const XSECEnv &secEnv, const DOMElement *sigElem) { DOMNodeList *keyInfos = sigElem->getElementsByTagName(MAKE_UNICODE_STRING("ds:X509Data")); if (keyInfos->getLength() == 0) { return auto_ptr<DSIGKeyInfoX509>(NULL); } auto_ptr<DSIGKeyInfoX509> keyInfo(new DSIGKeyInfoX509(&secEnv, keyInfos->item(0))); keyInfo->load(); return keyInfo; }
void DSIGKeyInfoName::load(void) { // Assuming we have a valid DOM_Node to start with, load the signing key so that it can // be used later on if (mp_keyInfoDOMNode == NULL) { // Attempt to load an empty signature element throw XSECException(XSECException::LoadEmptyInfoName); } if (!strEquals(getDSIGLocalName(mp_keyInfoDOMNode), "KeyName")) { throw XSECException(XSECException::LoadNonInfoName); } // Now find the text node containing the name DOMNode *tmpElt = mp_keyInfoDOMNode->getFirstChild(); while (tmpElt != 0 && tmpElt->getNodeType() != DOMNode::TEXT_NODE) tmpElt = tmpElt->getNextSibling(); if (tmpElt != 0) { mp_keyNameTextNode = tmpElt; mp_name = tmpElt->getNodeValue(); } else { throw XSECException(XSECException::ExpectedDSIGChildNotFound, MAKE_UNICODE_STRING("Expected TEXT node as child to <KeyName> element")); } }
void DSIGKeyInfoName::setKeyName(const XMLCh * name, bool isDName) { if (mp_keyNameTextNode == 0) { // Attempt to load an empty element throw XSECException(XSECException::LoadEmptySignature, MAKE_UNICODE_STRING("KeyInfoName::set() called prior to load() or createBlank()")); } if (mp_decodedDName != NULL) { XSEC_RELEASE_XMLCH(mp_decodedDName); mp_decodedDName = NULL; } if (isDName == true) { // This name should be treated as a Distinguished Name - so do the // required encoding mp_decodedDName = XMLString::replicate(name); XMLCh * encodedName = encodeDName(name); mp_keyNameTextNode->setNodeValue(encodedName); XSEC_RELEASE_XMLCH(encodedName); } else { mp_keyNameTextNode->setNodeValue(name); } mp_name = mp_keyNameTextNode->getNodeValue(); }
XERCES_CPP_NAMESPACE_USE #if !defined(XSEC_NO_XPATH) #include <iostream> #define KLUDGE_PREFIX "berindsig" // Helper function void setXPathNS(DOMDocument *d, DOMNamedNodeMap *xAtts, XSECXPathNodeList &addedNodes, XSECSafeBufferFormatter *formatter, XSECNameSpaceExpander * nse) { // if set then set the name spaces in the attribute list else clear them DOMElement * e = d->getDocumentElement(); if (e == NULL) { throw XSECException(XSECException::XPathError, "Element node not found in Document"); } if (xAtts != 0) { int xAttsCount = xAtts->getLength(); // Check all is OK with the Xalan Document and first element if (d == NULL) { throw XSECException(XSECException::XPathError, "Attempt to define XPath Name Space before setInput called"); } // Run through each attribute looking for name spaces const XMLCh *xpName; safeBuffer xpNameSB; const XMLCh *xpLocalName; const XMLCh *xpValue; for (int xCounter = 0; xCounter < xAttsCount; ++xCounter) { if (nse == NULL || !nse->nodeWasAdded(xAtts->item(xCounter))) { xpName = xAtts->item(xCounter)->getNodeName(); xpNameSB << (*formatter << xpName); if (xpNameSB.sbStrncmp("xmlns", 5) == 0) { // Check whether a node of this name already exists xpLocalName = xAtts->item(xCounter)->getLocalName(); xpValue = xAtts->item(xCounter)->getNodeValue(); if (e->hasAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, xpLocalName) == false) { // Nope e->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, xpName, xpValue); addedNodes.addNode(e->getAttributeNodeNS(DSIGConstants::s_unicodeStrURIXMLNS, xpLocalName)); } } } } } // Insert the kludge namespace safeBuffer k("xmlns:"); k.sbStrcatIn(KLUDGE_PREFIX); e->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, MAKE_UNICODE_STRING(k.rawCharBuffer()), DSIGConstants::s_unicodeStrURIDSIG); }
static bool SAMLCheckSubject(const DOMDocument *doc, SAMLTokenData &token) { const DOMElement *subject; char *name = g_strdup_printf("%sSubject", token.ns.c_str()); subject = SAMLFindChildByName(doc->getDocumentElement(), name); g_free(name); if (NULL == subject) { // Should not happen, since this is required element in the schema. Log("%s: Missing subject element!\n", __FUNCTION__); // ASSERT(0); return false; } const DOMElement *nameID; name = g_strdup_printf("%sNameID", token.ns.c_str()); nameID = SAMLFindChildByName(subject, name); g_free(name); if (NULL == nameID) { /* * The schema allows BaseID, NameID, or EncryptedID. The library code * for the SSO server only supports NameID. EncryptedID is really * complicated (and we don't have decryption keys, so let's not * support it for now. */ Log("%s: No NameID element for the subject.\n", __FUNCTION__); return false; } token.subjectName = SAMLStringWrapper(nameID->getTextContent()).c_str(); Debug("%s: subjectName: '%s'\n", __FUNCTION__, token.subjectName.c_str()); /* * TODO: Investigate: NameID elements can have a NameQualifier attribute. * This smells like a domain name, and we might want to include it with * subject name (<NameQualifier>\subjectName). */ /* * Find all the SubjectConfirmation nodes and see if at least one can be * verified. */ name = g_strdup_printf("%sSubjectConfirmation", token.ns.c_str()); XMLT scName(name); g_free(name); for (DOMElement *child = subject->getFirstElementChild(); child != NULL; child = child->getNextElementSibling()) { if (!XMLString::equals(child->getNodeName(), scName.getUnicodeStr())) { continue; } const XMLCh *method = child->getAttribute(MAKE_UNICODE_STRING("Method")); if ((NULL == method) || (0 == *method)) { // Should not happen, since this is a required attribute. ASSERT(0); Debug("%s: Missing confirmation method.\n", __FUNCTION__); continue; } if (!XMLString::equals( MAKE_UNICODE_STRING("urn:oasis:names:tc:SAML:2.0:cm:bearer"), method)) { Debug("%s: Non-bearer confirmation method in token", __FUNCTION__); continue; } const DOMElement *subjConfirmData; name = g_strdup_printf("%sSubjectConfirmationData", token.ns.c_str()); subjConfirmData = SAMLFindChildByName(child, name); g_free(name); if (NULL != subjConfirmData) { if (!SAMLCheckTimeAttr(subjConfirmData, "NotBefore", true) || !SAMLCheckTimeAttr(subjConfirmData, "NotOnOrAfter", false)) { Warning("%s: subjConfirmData time check failed\n", __FUNCTION__); continue; } const XMLCh *recipient; recipient = subjConfirmData->getAttribute( MAKE_UNICODE_STRING("Recipient")); /* * getAttribute() returns a 0-length string, not NULL, if it can't * find what it wants. */ if ((0 != XMLString::stringLen(recipient)) && !SAMLCheckAudience(recipient)) { Debug("%s: failed recipient check\n", __FUNCTION__); continue; } } return true; } Debug("%s: Could not verify using any SubjectConfirmation elements\n", __FUNCTION__); return false; }
void DSIGReference::setType(const XMLCh *type) { if (mp_referenceNode) ((DOMElement*)mp_referenceNode)->setAttributeNS(NULL, MAKE_UNICODE_STRING("Type"), type); }
void DSIGReference::setId(const XMLCh *id) { if (mp_referenceNode) ((DOMElement*)mp_referenceNode)->setAttributeNS(NULL, MAKE_UNICODE_STRING("Id"), id); }
DOMElement *DSIGReference::createBlankReference(const XMLCh * URI, const XMLCh * hashAlgorithmURI, const XMLCh * type) { // Reset this Reference just in case m_isManifest = false; mp_preHash = NULL; mp_manifestList = NULL; mp_transformsNode = NULL; mp_transformList = NULL; XSECmapURIToHashMethod(hashAlgorithmURI, me_hashMethod); safeBuffer str; DOMDocument *doc = mp_env->getParentDocument(); const XMLCh * prefix = mp_env->getDSIGNSPrefix(); makeQName(str, prefix, "Reference"); DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer()); mp_referenceNode = ret; // Set type if (type != NULL) ret->setAttributeNS(NULL, MAKE_UNICODE_STRING("Type"), type); // Set URI if (URI != NULL) { ret->setAttributeNS(NULL, s_unicodeStrURI, URI); mp_URI = ret->getAttributeNS(NULL, s_unicodeStrURI); // Used later on as a pointer } else { // Anonymous reference mp_URI = NULL; } // Create hash and hashValue nodes makeQName(str, prefix, "DigestMethod"); DOMElement *digestMethod = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer()); mp_env->doPrettyPrint(ret); ret->appendChild(digestMethod); mp_env->doPrettyPrint(ret); digestMethod->setAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm, hashAlgorithmURI); // Retrieve the attribute value for later use mp_algorithmURI = digestMethod->getAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm); // DigestValue makeQName(str, prefix, "DigestValue"); mp_hashValueNode = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer()); ret->appendChild(mp_hashValueNode); mp_env->doPrettyPrint(ret); mp_hashValueNode->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("Not yet calculated"))); m_loaded = true; return ret; }
void DSIGReference::setHash(void) { // First determine the hash value XMLByte calculatedHashVal[CRYPTO_MAX_HASH_SIZE]; // The hash that we determined unsigned int calculatedHashLen; XMLByte base64Hash [CRYPTO_MAX_HASH_SIZE * 2]; unsigned int base64HashLen; calculatedHashLen = calculateHash(calculatedHashVal, CRYPTO_MAX_HASH_SIZE); // Calculate the base64 value XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64(); if (!b64) { throw XSECException(XSECException::CryptoProviderError, "Error requesting Base64 object from Crypto Provider"); } Janitor<XSECCryptoBase64> j_b64(b64); b64->encodeInit(); base64HashLen = b64->encode(calculatedHashVal, calculatedHashLen, base64Hash, CRYPTO_MAX_HASH_SIZE * 2); base64HashLen += b64->encodeFinish(&base64Hash[base64HashLen], (CRYPTO_MAX_HASH_SIZE * 2) - base64HashLen); // Ensure the string is terminated if (base64Hash[base64HashLen-1] == '\n') base64Hash[base64HashLen-1] = '\0'; else base64Hash[base64HashLen] = '\0'; // Now find the correct text node to re-set DOMNode *tmpElt = mp_hashValueNode; if (mp_hashValueNode == 0) { throw XSECException(XSECException::NotLoaded, "setHash() called in DSIGReference before load()"); } tmpElt = mp_hashValueNode->getFirstChild(); while (tmpElt != NULL && tmpElt->getNodeType() != DOMNode::TEXT_NODE) tmpElt = tmpElt->getNextSibling(); if (tmpElt == NULL) { // Need to create the underlying TEXT_NODE DOMDocument *doc = mp_referenceNode->getOwnerDocument(); tmpElt = doc->createTextNode(MAKE_UNICODE_STRING((char *) base64Hash)); mp_hashValueNode->appendChild(tmpElt); } else { tmpElt->setNodeValue(MAKE_UNICODE_STRING((char *) base64Hash)); } }
int main (int argc, char **argv) { try { XMLPlatformUtils::Initialize(); #ifndef XSEC_NO_XALAN XalanTransformer::initialize(); #endif XSECPlatformUtils::Initialise(); } catch (const XMLException &e) { cerr << "Error during initialisation of Xerces" << endl; cerr << "Error Message = : " << e.getMessage() << endl; } // Create a blank Document DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(MAKE_UNICODE_STRING("Core")); // Create a letter DOMDocument *doc = createLetter(impl); try { /* Create the cipher object that we need */ XSECProvider prov; XENCCipher *cipher; cipher = prov.newCipher(doc); /* Now generate a random key that we can use to encrypt the element * * First check the status of the random generation in OpenSSL */ if (RAND_status() != 1) { cerr << "OpenSSL random generation not properly initialised" << endl; exit(1); } unsigned char keyBuf[24]; if (RAND_bytes(keyBuf, 24) == 0) { cerr << "Error obtaining 24 bytes of random from OpenSSL" << endl; exit(1); } /* Wrap this in a Symmetric 3DES key */ OpenSSLCryptoSymmetricKey * key = new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_3DES_192); key->setKey(keyBuf, 24); cipher->setKey(key); /* Encrypt the element that needs to be hidden */ cipher->encryptElement(g_toEncrypt, ENCRYPT_3DES_CBC); /* Now lets create an EncryptedKey element to hold the generated key */ /* First lets load the public key in the certificate */ OpenSSLCryptoX509 * x509 = new OpenSSLCryptoX509(); x509->loadX509Base64Bin(cert, (unsigned int) strlen(cert)); /* Now set the Key Encrypting Key (NOTE: Not the normal key) */ cipher->setKEK(x509->clonePublicKey()); /* Now do the encrypt, using RSA with PKCS 1.5 padding */ XENCEncryptedKey * encryptedKey = cipher->encryptKey(keyBuf, 24, ENCRYPT_RSA_15); /* * Add the encrypted Key to the previously created EncryptedData, which * we first retrieve from the cipher object. This will automatically create * the appropriate <KeyInfo> element within the EncryptedData */ XENCEncryptedData * encryptedData = cipher->getEncryptedData(); encryptedData->appendEncryptedKey(encryptedKey); } catch (XSECException &e) { char * msg = XMLString::transcode(e.getMsg()); cerr << "An error occurred during an encryption operation\n Message: " << msg << endl; exit(1); } /* Output */ docSetup(doc); cout << doc; return 0; }
zwOXsnCVZFfJsB9gtTxZLaY7UE2dgrz47iplFecxL5mM7iKOklmGlWTfzyY87BGT\n\ GlQPlPBoX19WBf67Lhc1wovK+hVXdyzf/6VxxMKAxnSVHZaXVRLl9YhSpTUCAwEA\n\ AaOCAQEwgf4wCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l\n\ cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFGq6U1SwYNRyTJGAwARirEdavfXB\n\ MIGjBgNVHSMEgZswgZiAFBKNX9CsAIsjUIFmVq4wE4wlOGC5oX2kezB5MQswCQYD\n\ VQQGEwJBVTEMMAoGA1UECBMDVmljMRIwEAYDVQQHEwlNZWxib3VybmUxHzAdBgNV\n\ BAoTFlhNTC1TZWN1cml0eS1DIFByb2plY3QxEDAOBgNVBAsTB1hTRUMtQ0ExFTAT\n\ BgNVBAMTDFhTRUMtQ0EgUm9vdIIBADAJBgcqhkjOOAQDAy8AMCwCFGoKhVPnDeg9\n\ nbEFo2KDDlG/NiUqAhRJxQPLXDhehQjn6eqQWOUlkFtA9A=="; DOMDocument *createLetter(DOMImplementation *impl) { DOMDocument *doc = impl->createDocument( 0, MAKE_UNICODE_STRING("Letter"), NULL); DOMElement *rootElem = doc->getDocumentElement(); // Add the ToAddress DOMElement *addressElem = doc->createElement(MAKE_UNICODE_STRING("ToAddress")); rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n"))); rootElem->appendChild(addressElem); addressElem->appendChild(doc->createTextNode( MAKE_UNICODE_STRING("The address of the Recipient"))); // Add the FromAddress addressElem = doc->createElement(MAKE_UNICODE_STRING("FromAddress")); rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
void DSIGKeyInfoValue::setDSAP(const char * P) { m_P.sbStrcpyIn(P); mp_PTextNode->setNodeValue(MAKE_UNICODE_STRING(P)); }
DOMElement * DSIGKeyInfoValue::createBlankDSAKeyValue(const char * P, const char * Q, const char * G, const char * Y) { // Set the strings m_P.sbStrcpyIn(P); m_Q.sbStrcpyIn(Q); m_G.sbStrcpyIn(G); m_Y.sbStrcpyIn(Y); // Set our type m_keyInfoType = KEYINFO_VALUE_DSA; // Create the DOM Structure safeBuffer str; DOMDocument *doc = mp_parentSignature->getParentDocument(); safeBuffer prefix = mp_parentSignature->getDSIGNSPrefix(); makeQName(str, prefix, "KeyValue"); DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); mp_valueNode = ret; makeQName(str, prefix, "DSAKeyValue"); DOMElement * dsa = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); ret->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); ret->appendChild(dsa); dsa->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); ret->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); // Now create the value children makeQName(str, prefix, "P"); DOMElement * v = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); mp_PTextNode = doc->createTextNode(MAKE_UNICODE_STRING(P)); dsa->appendChild(v); dsa->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); v->appendChild(mp_PTextNode); makeQName(str, prefix, "Q"); v = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); mp_PTextNode = doc->createTextNode(MAKE_UNICODE_STRING(Q)); dsa->appendChild(v); dsa->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); v->appendChild(mp_PTextNode); makeQName(str, prefix, "G"); v = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); mp_PTextNode = doc->createTextNode(MAKE_UNICODE_STRING(G)); dsa->appendChild(v); dsa->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); v->appendChild(mp_PTextNode); makeQName(str, prefix, "Y"); v = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.sbStrToXMLCh()); mp_PTextNode = doc->createTextNode(MAKE_UNICODE_STRING(Y)); dsa->appendChild(v); dsa->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL)); v->appendChild(mp_PTextNode); return ret; }