New KeyResolver/Validator/Encrypter/Decrypter classes.
[shibboleth/cpp-xmltooling.git] / xmltoolingtest / SignatureTest.h
index 62bd6a3..458fa7e 100644 (file)
@@ -16,6 +16,8 @@
 \r
 #include "XMLObjectBaseTestCase.h"\r
 \r
+#include <xmltooling/signature/SignatureValidator.h>\r
+\r
 #include <fstream>\r
 #include <openssl/pem.h>\r
 #include <xercesc/util/XMLUniDefs.hpp>\r
 #include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
 #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
+#include <xsec/enc/XSECCryptoException.hpp>\r
+#include <xsec/framework/XSECException.hpp>\r
 \r
-class TestContext : public SigningContext, public VerifyingContext, CredentialResolver\r
+class TestContext : public ContentReference\r
 {\r
-    XSECCryptoKey* m_key;\r
-    vector<XSECCryptoX509*> m_certs;\r
     XMLCh* m_uri;\r
     \r
 public:\r
     TestContext(const XMLCh* uri) {\r
-        string keypath=data_path + "key.pem";\r
-        BIO* in=BIO_new(BIO_s_file_internal());\r
-        if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
-            EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
-            if (pkey) {\r
-                m_key=new OpenSSLCryptoKeyRSA(pkey);\r
-                EVP_PKEY_free(pkey);\r
-            }\r
-        }\r
-        if (in) BIO_free(in);\r
-        TS_ASSERT(m_key!=NULL);\r
-\r
-        string certpath=data_path + "cert.pem";\r
-        in=BIO_new(BIO_s_file_internal());\r
-        if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
-            X509* x=NULL;\r
-            while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
-                m_certs.push_back(new OpenSSLCryptoX509(x));\r
-                X509_free(x);\r
-            }\r
-        }\r
-        if (in) BIO_free(in);\r
-        TS_ASSERT(m_certs.size()>0);\r
-        \r
         m_uri=XMLString::replicate(uri);\r
     }\r
     \r
     virtual ~TestContext() {\r
-        delete m_key;\r
-        for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
         XMLString::release(&m_uri);\r
     }\r
 \r
-    bool createSignature(DSIGSignature* sig) {\r
+    void createReferences(DSIGSignature* sig) {\r
         DSIGReference* ref=sig->createReference(m_uri);\r
         ref->appendEnvelopedSignatureTransform();\r
         ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
-        return false;\r
+    }\r
+};\r
+\r
+class TestValidator : public SignatureValidator\r
+{\r
+    XMLCh* m_uri;\r
+    \r
+    TestValidator(const TestValidator& src) : SignatureValidator(src) {\r
+        m_uri=XMLString::replicate(src.m_uri);\r
+    }\r
+\r
+public:\r
+    TestValidator(const XMLCh* uri, XSECCryptoKey* key) : SignatureValidator(new KeyResolver(key)) {\r
+        m_uri=XMLString::replicate(uri);\r
+    }\r
+    \r
+    virtual ~TestValidator() {\r
+        XMLString::release(&m_uri);\r
     }\r
 \r
-    void verifySignature(DSIGSignature* sig) const {\r
+    TestValidator* clone() const {\r
+        return new TestValidator(*this);\r
+    }\r
+\r
+    void validate(const Signature* sigObj) const {\r
+        DSIGSignature* sig=sigObj->getXMLSignature();\r
+        if (!sig)\r
+            throw SignatureException("Only a marshalled Signature object can be verified.");\r
         const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
         TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
-        XSECKeyInfoResolverDefault resolver;\r
-        sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us.\r
-        sig->verify();\r
+        SignatureValidator::validate(sigObj);\r
+    }\r
+};\r
+\r
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
+public:\r
+    void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
+        safeBuffer& buf=cert->getDEREncodingSB();\r
+        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
+        x->setValue(buf.sbStrToXMLCh());\r
+        bag->getX509Certificates().push_back(x);\r
     }\r
-    \r
-    KeyInfo* getKeyInfo() { return NULL; }\r
-    CredentialResolver& getCredentialResolver() { return *this; }\r
-    const char* getId() const { return "test"; }\r
-    const std::vector<XSECCryptoX509*>* getX509Certificates() { return &m_certs; }\r
-    XSECCryptoKey* getPublicKey() { return m_key; }\r
-    XSECCryptoKey* getPrivateKey() { return m_key; }\r
-    Lockable& lock() { return *this; }\r
-    void unlock() {}\r
 };\r
 \r
 class SignatureTest : public CxxTest::TestSuite {\r
+    XSECCryptoKey* m_key;\r
+    vector<XSECCryptoX509*> m_certs;\r
 public:\r
     void setUp() {\r
         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
+        string keypath=data_path + "key.pem";\r
+        BIO* in=BIO_new(BIO_s_file_internal());\r
+        if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
+            EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
+            if (pkey) {\r
+                m_key=new OpenSSLCryptoKeyRSA(pkey);\r
+                EVP_PKEY_free(pkey);\r
+            }\r
+        }\r
+        if (in) BIO_free(in);\r
+        TS_ASSERT(m_key!=NULL);\r
+\r
+        string certpath=data_path + "cert.pem";\r
+        in=BIO_new(BIO_s_file_internal());\r
+        if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
+            X509* x=NULL;\r
+            while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
+                m_certs.push_back(new OpenSSLCryptoX509(x));\r
+                X509_free(x);\r
+            }\r
+        }\r
+        if (in) BIO_free(in);\r
+        TS_ASSERT(m_certs.size()>0);\r
+        \r
     }\r
 \r
     void tearDown() {\r
@@ -104,6 +129,8 @@ public:
         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
         XMLObjectBuilder::deregisterBuilder(qname);\r
         XMLObjectBuilder::deregisterBuilder(qtype);\r
+        delete m_key;\r
+        for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
     }\r
 \r
     void testSignature() {\r
@@ -126,13 +153,28 @@ public:
         kids[1]->setValue(bar.get());\r
         \r
         // Append a Signature.\r
-        Signature* sig=SignatureBuilder::newSignature();\r
+        Signature* sig=SignatureBuilder::buildSignature();\r
         sxObject->setSignature(sig);\r
+        sig->setContentReference(new TestContext(&chNull));\r
+        sig->setSigningKey(m_key->clone());\r
+        \r
+        // Build KeyInfo.\r
+        KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
+        X509Data* x509Data=X509DataBuilder::buildX509Data();\r
+        keyInfo->getX509Datas().push_back(x509Data);\r
+        for_each(m_certs.begin(),m_certs.end(),bind1st(_addcert(),x509Data));\r
+        sig->setKeyInfo(keyInfo);\r
         \r
         // Signing context for the whole document.\r
-        TestContext tc(&chNull);\r
-        MarshallingContext mctx(sig,&tc);\r
-        DOMElement* rootElement = sxObject->marshall((DOMDocument*)NULL,&mctx);\r
+        vector<Signature*> sigs(1,sig);\r
+        DOMElement* rootElement = NULL;\r
+        try {\r
+            rootElement=sxObject->marshall((DOMDocument*)NULL,&sigs);\r
+        }\r
+        catch (XMLToolingException& e) {\r
+            TS_TRACE(e.what());\r
+            throw;\r
+        }\r
         \r
         string buf;\r
         XMLHelper::serialize(rootElement, buf);\r
@@ -143,11 +185,12 @@ public:
         auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));\r
         TS_ASSERT(sxObject2.get()!=NULL);\r
         TS_ASSERT(sxObject2->getSignature()!=NULL);\r
+        sxObject2->getSignature()->registerValidator(new TestValidator(&chNull,m_key->clone()));\r
         \r
         try {\r
-            sxObject2->getSignature()->verify(tc);\r
+            sxObject2->getSignature()->validate(false);\r
         }\r
-        catch (SignatureException& e) {\r
+        catch (XMLToolingException& e) {\r
             TS_TRACE(e.what());\r
             throw;\r
         }\r