1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*
21 * XSEC
22 *
23 * TXFMCipher := Class that performs encryption and decryption transforms
24 *
25 * $Id: TXFMCipher.cpp 1817135 2017-12-04 22:24:05Z scantor $
26 *
27 */
28
29 // XSEC
30
31 #include <xsec/framework/XSECDefs.hpp>
32 #include <xsec/transformers/TXFMCipher.hpp>
33 #include <xsec/utils/XSECPlatformUtils.hpp>
34 #include <xsec/framework/XSECException.hpp>
35
36 XERCES_CPP_NAMESPACE_USE
37
TXFMCipher(DOMDocument * doc,const XSECCryptoKey * key,bool encrypt,XSECCryptoSymmetricKey::SymmetricKeyMode mode,unsigned int taglen)38 TXFMCipher::TXFMCipher(DOMDocument *doc,
39 const XSECCryptoKey * key,
40 bool encrypt,
41 XSECCryptoSymmetricKey::SymmetricKeyMode mode,
42 unsigned int taglen) :
43 TXFMBase(doc),
44 m_doEncrypt(encrypt),
45 m_taglen(taglen),
46 mp_cipher(NULL),
47 m_remaining(0) {
48
49 if (key && key->getKeyType() == XSECCryptoKey::KEY_SYMMETRIC)
50 mp_cipher = key->clone();
51
52 if (!mp_cipher) {
53 throw XSECException(XSECException::CryptoProviderError,
54 "Error cloning key, or not a symmetric key");
55 }
56
57 m_complete = false;
58
59 try {
60 if (m_doEncrypt)
61 ((XSECCryptoSymmetricKey *) (mp_cipher))->encryptInit((mode != XSECCryptoSymmetricKey::MODE_GCM), mode);
62 else
63 ((XSECCryptoSymmetricKey *) (mp_cipher))->decryptInit((mode != XSECCryptoSymmetricKey::MODE_GCM), mode);
64 }
65 catch (...) {
66 delete mp_cipher;
67 mp_cipher = NULL;
68 throw;
69 }
70
71 };
72
~TXFMCipher()73 TXFMCipher::~TXFMCipher() {
74
75 delete mp_cipher;
76
77 };
78
79 // Methods to set the inputs
80
setInput(TXFMBase * newInput)81 void TXFMCipher::setInput(TXFMBase *newInput) {
82
83 input = newInput;
84
85 // Set up for comments
86 keepComments = input->getCommentsStatus();
87
88 }
89
90 // Methods to get tranform output type and input requirement
91
getInputType(void) const92 TXFMBase::ioType TXFMCipher::getInputType(void) const {
93
94 return TXFMBase::BYTE_STREAM;
95
96 }
getOutputType(void) const97 TXFMBase::ioType TXFMCipher::getOutputType(void) const {
98
99 return TXFMBase::BYTE_STREAM;
100
101 }
102
103
getNodeType(void) const104 TXFMBase::nodeType TXFMCipher::getNodeType(void) const {
105
106 return TXFMBase::DOM_NODE_NONE;
107
108 }
109
110 // Methods to get output data
111
readBytes(XMLByte * const toFill,unsigned int maxToFill)112 unsigned int TXFMCipher::readBytes(XMLByte * const toFill, unsigned int maxToFill) {
113
114 unsigned int ret, fill, leftToFill;
115
116 ret = 0; // How much have we copied?
117 leftToFill = maxToFill; // Still have to copy in entire thing
118
119 while (ret != maxToFill && (m_complete == false || m_remaining > 0)) {
120
121 if (m_remaining != 0) {
122
123 // Copy anything remaining in the buffer to the output
124
125 fill = (leftToFill > m_remaining ? m_remaining : leftToFill);
126 memcpy(&toFill[ret], m_outputBuffer, fill);
127
128 if (fill < m_remaining)
129 memmove(m_outputBuffer, m_outputBuffer + fill, (m_remaining - fill));
130
131 m_remaining -= fill;
132 leftToFill -= fill;
133 ret += fill;
134 }
135
136 // Now do some crypting
137
138 if (m_complete == false && m_remaining == 0) {
139
140 unsigned int sz = input->readBytes(m_inputBuffer, 2048);
141
142 XSECCryptoSymmetricKey * symCipher =
143 (XSECCryptoSymmetricKey*) mp_cipher;
144 if (m_doEncrypt) {
145
146 if (sz == 0) {
147 m_complete = true;
148 m_remaining = symCipher->encryptFinish(m_outputBuffer, 3072, m_taglen);
149 }
150 else
151 m_remaining = symCipher->encrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
152 }
153 else {
154
155 if (sz == 0) {
156 m_complete = true;
157 m_remaining = symCipher->decryptFinish(m_outputBuffer, 3072);
158 }
159 else
160 m_remaining = symCipher->decrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
161 }
162 }
163
164 }
165
166 return ret;
167
168 }
169