c3358faa33e1045e2f30439941cee6b1c1bad9bf
[shibboleth/cpp-opensaml.git] / saml / binding / impl / SAMLArtifact.cpp
1 /*
2  *  Copyright 2001-2007 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * SAMLArtifact.cpp
19  * 
20  * Base class for SAML 1.x and 2.0 artifacts 
21  */
22
23 #include "internal.h"
24 #include "binding/SAMLArtifact.h"
25
26 #include <xercesc/util/Base64.hpp>
27
28 using namespace opensaml;
29 using namespace xmltooling;
30 using namespace std;
31
32 namespace opensaml {
33     namespace saml1p {
34         SAML_DLLLOCAL PluginManager<SAMLArtifact,string,const char*>::Factory SAMLArtifactType0001Factory; 
35         SAML_DLLLOCAL PluginManager<SAMLArtifact,string,const char*>::Factory SAMLArtifactType0002Factory; 
36     };
37
38     namespace saml2p {
39         SAML_DLLLOCAL PluginManager<SAMLArtifact,string,const char*>::Factory SAML2ArtifactType0004Factory; 
40     };
41 };
42
43 void SAML_API opensaml::registerSAMLArtifacts()
44 {
45     SAMLConfig& conf=SAMLConfig::getConfig();
46
47     string typecode;
48     typecode+=(char)0x0;
49     typecode+=(char)0x1;
50     conf.SAMLArtifactManager.registerFactory(typecode, saml1p::SAMLArtifactType0001Factory);
51     typecode[1]=(char)0x2;
52     conf.SAMLArtifactManager.registerFactory(typecode, saml1p::SAMLArtifactType0002Factory);
53     typecode[1]=(char)0x4;
54     conf.SAMLArtifactManager.registerFactory(typecode, saml2p::SAML2ArtifactType0004Factory);
55 }
56
57 const unsigned int SAMLArtifact::TYPECODE_LENGTH = 2;
58
59 // Basic constructor just decodes the string and saves it off.
60 // Subclasses will handle pulling it apart.
61
62 SAMLArtifact::SAMLArtifact(const char* s)
63 {
64     xsecsize_t len=0;
65     XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(s),&len);
66     if (!decoded)
67         throw ArtifactException("Unable to decode base64 artifact.");
68     XMLByte* ptr=decoded;
69     while (len--)
70         m_raw+= *ptr++;
71 #ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE
72     XMLString::release(&decoded);
73 #else
74     XMLString::release((char**)&decoded);
75 #endif
76 }
77
78 string SAMLArtifact::encode() const
79 {
80     xsecsize_t len=0;
81     XMLByte* out=Base64::encode(reinterpret_cast<const XMLByte*>(m_raw.data()),m_raw.size(),&len);
82     if (out) {
83         string ret(reinterpret_cast<char*>(out),len);
84 #ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE
85         XMLString::release(&out);
86 #else
87         XMLString::release((char**)&out);
88 #endif
89         return ret;
90     }
91     return string();
92 }
93
94 SAMLArtifact* SAMLArtifact::parse(const char* s)
95 {
96     // Decode and extract the type code first.
97     xsecsize_t len=0;
98     XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(s),&len);
99     if (!decoded)
100         throw ArtifactException("Artifact parser unable to decode base64-encoded artifact.");
101     
102     string type;
103     type+= decoded[0];
104     type+= decoded[1];
105 #ifdef OPENSAML_XERCESC_HAS_XMLBYTE_RELEASE
106     XMLString::release(&decoded);
107 #else
108     XMLString::release((char**)&decoded);
109 #endif
110     
111     return SAMLConfig::getConfig().SAMLArtifactManager.newPlugin(type,s);
112 }
113
114 string SAMLArtifact::toHex(const string& s)
115 {
116     static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
117     string::size_type len = s.length();
118     string ret;
119     
120     // two characters form the hex value.
121     for (string::size_type i=0; i < len; i++) {
122         ret+=(DIGITS[((unsigned char)(0xF0 & s[i])) >> 4 ]);
123         ret+=(DIGITS[0x0F & s[i]]);
124     }
125     return ret;
126 }