Moved artifact source code into binding folders.
[shibboleth/cpp-opensaml.git] / saml / binding / impl / SAMLArtifact.cpp
1 /*
2  *  Copyright 2001-2006 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,const char*>::Factory SAMLArtifactType0001Factory; 
35         SAML_DLLLOCAL PluginManager<SAMLArtifact,const char*>::Factory SAMLArtifactType0002Factory; 
36     };
37
38     namespace saml2p {
39         SAML_DLLLOCAL PluginManager<SAMLArtifact,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     unsigned int 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     XMLString::release(&decoded);
72 }
73
74 string SAMLArtifact::encode() const
75 {
76     unsigned int len=0;
77     XMLByte* out=Base64::encode(reinterpret_cast<const XMLByte*>(m_raw.data()),m_raw.size(),&len);
78     if (out) {
79         string ret(reinterpret_cast<char*>(out),len);
80         XMLString::release(&out);
81         return ret;
82     }
83     return string();
84 }
85
86 SAMLArtifact* SAMLArtifact::parse(const char* s)
87 {
88     // Decode and extract the type code first.
89     unsigned int len=0;
90     XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(s),&len);
91     if (!decoded)
92         throw ArtifactException("Artifact parser unable to decode base64-encoded artifact.");
93     
94     string type;
95     type+= decoded[0];
96     type+= decoded[1];
97     XMLString::release(&decoded);
98     
99     return SAMLConfig::getConfig().SAMLArtifactManager.newPlugin(type,s);
100 }
101
102 string SAMLArtifact::toHex(const string& s)
103 {
104     static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
105     string::size_type len = s.length();
106     string ret;
107     
108     // two characters form the hex value.
109     for (string::size_type i=0; i < len; i++) {
110         ret+=(DIGITS[((unsigned char)(0xF0 & s[i])) >> 4 ]);
111         ret+=(DIGITS[0x0F & s[i]]);
112     }
113     return ret;
114 }