Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[shibboleth/cpp-xmltooling.git] / xmltooling / security / impl / OpenSSLCryptoX509CRL.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * OpenSSLCryptoX509CRL.cpp
23  * 
24  * OpenSSL-based class for handling X.509 CRLs.
25  */
26
27 #include "internal.h"
28 #include "security/OpenSSLCryptoX509CRL.h"
29
30 #include <xsec/framework/XSECError.hpp>
31 #include <xsec/enc/XSECCryptoException.hpp>
32 #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
33
34 #include <xercesc/util/Janitor.hpp>
35
36 XSEC_USING_XERCES(ArrayJanitor);
37 XSEC_USING_XERCES(Janitor);
38
39 using namespace xmltooling;
40
41 OpenSSLCryptoX509CRL::OpenSSLCryptoX509CRL() : mp_X509CRL(nullptr), m_DERX509CRL("")
42 {
43 }
44
45 OpenSSLCryptoX509CRL::~OpenSSLCryptoX509CRL()
46 {
47         if (mp_X509CRL)
48                 X509_CRL_free(mp_X509CRL);
49 }
50
51 OpenSSLCryptoX509CRL::OpenSSLCryptoX509CRL(X509_CRL* x) {
52
53         // Build this from an existing X509_CRL structure
54
55         mp_X509CRL = X509_CRL_dup(x);
56         
57         // Now need to create the DER encoding
58
59         BIO* b64 = BIO_new(BIO_f_base64());
60         BIO* bmem = BIO_new(BIO_s_mem());
61
62         BIO_set_mem_eof_return(bmem, 0);
63         b64 = BIO_push(b64, bmem);
64
65         // Translate X509 to Base64
66
67         i2d_X509_CRL_bio(b64, x);
68
69         BIO_flush(b64);
70
71         char buf[1024];
72         unsigned int l;
73         
74         m_DERX509CRL.sbStrcpyIn("");
75
76         while ((l = BIO_read(bmem, buf, 1023)) > 0) {
77                 buf[l] = '\0';
78                 m_DERX509CRL.sbStrcatIn(buf);
79         }
80
81         BIO_free_all(b64);
82 }
83
84 const XMLCh* OpenSSLCryptoX509CRL::getProviderName() const
85 {
86     return DSIGConstants::s_unicodeStrPROVOpenSSL;
87 }
88
89 void OpenSSLCryptoX509CRL::loadX509CRLBase64Bin(const char* buf, unsigned int len)
90 {
91
92         // Free anything currently held.
93         
94         if (mp_X509CRL)
95                 X509_CRL_free(mp_X509CRL);
96         
97         int bufLen = len;
98         unsigned char* outBuf;
99         XSECnew(outBuf, unsigned char[len + 1]);
100         ArrayJanitor<unsigned char> j_outBuf(outBuf);
101
102         XSCryptCryptoBase64 *b64;
103         XSECnew(b64, XSCryptCryptoBase64);
104         Janitor<XSCryptCryptoBase64> j_b64(b64);
105
106         b64->decodeInit();
107         bufLen = b64->decode((unsigned char *) buf, len, outBuf, len);
108         bufLen += b64->decodeFinish(&outBuf[bufLen], len-bufLen);
109
110         if (bufLen > 0) {
111 #if defined(XSEC_OPENSSL_D2IX509_CONST_BUFFER)
112                 mp_X509CRL=  d2i_X509_CRL(nullptr, (const unsigned char **) (&outBuf), bufLen);
113 #else
114                 mp_X509CRL=  d2i_X509_CRL(nullptr, &outBuf, bufLen);
115 #endif
116         }
117
118         // Check to see if we have a CRL....
119         if (mp_X509CRL == nullptr) {
120                 throw XSECCryptoException(XSECCryptoException::X509Error,
121                 "OpenSSL:X509CRL - Error translating Base64 DER encoding into OpenSSL X509 CRL structure");
122         }
123
124         m_DERX509CRL.sbStrcpyIn(buf);
125
126 }
127
128 safeBuffer& OpenSSLCryptoX509CRL::getDEREncodingSB()
129 {
130     return m_DERX509CRL;
131 }
132
133 X509_CRL* OpenSSLCryptoX509CRL::getOpenSSLX509CRL()
134 {
135     return mp_X509CRL;
136 }
137
138 XSECCryptoX509CRL* OpenSSLCryptoX509CRL::clone() const
139 {
140     OpenSSLCryptoX509CRL* copy = new OpenSSLCryptoX509CRL();
141     copy->mp_X509CRL = X509_CRL_dup(mp_X509CRL);
142     copy->m_DERX509CRL = m_DERX509CRL;
143     return copy;
144 }