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  * XSECCryptoKeyRSA := RSA Keys
24  *
25  * Author(s): Berin Lautenbach
26  *
27  * $Id: OpenSSLCryptoKeyRSA.hpp 1818339 2017-12-15 21:13:08Z scantor $
28  *
29  */
30 
31 #ifndef OPENSSLCRYPTOKEYRSA_INCLUDE
32 #define OPENSSLCRYPTOKEYRSA_INCLUDE
33 
34 #include <xsec/enc/XSECCryptoKeyRSA.hpp>
35 
36 #if defined (XSEC_HAVE_OPENSSL)
37 #include <openssl/evp.h>
38 
39 /**
40  * \ingroup opensslcrypto
41  */
42 
43 /**
44  * \brief Implementation of the interface class for RSA keys.
45  *
46  * The library uses classes derived from this to process RSA keys.
47  */
48 
49 class XSEC_EXPORT OpenSSLCryptoKeyRSA : public XSECCryptoKeyRSA {
50 
51 public :
52 
53     /** @name Constructors and Destructors */
54     //@{
55 
56     OpenSSLCryptoKeyRSA();
57     virtual ~OpenSSLCryptoKeyRSA();
58 
59     //@}
60 
61     /** @name Key Interface methods */
62     //@{
63 
64     /**
65      * \brief Return the type of this key.
66      *
67      * For RSA keys, this allows people to determine whether this is a
68      * public key, private key or a key pair
69      */
70 
71     virtual XSECCryptoKey::KeyType getKeyType() const;
72 
73     /**
74      * \brief Return the OpenSSL identifier string
75      */
76 
77     virtual const XMLCh* getProviderName() const;
78 
79     /**
80      * \brief Replicate key
81      */
82 
83     virtual XSECCryptoKey* clone() const;
84 
85     //@}
86 
87     /** @name Mandatory RSA interface methods
88      *
89      * These methods are required by the library.
90      */
91     //@{
92 
93 
94     /**
95      * \brief Verify a SHA1 PKCS1 encoded signature
96      *
97      * The library will call this function to validate an RSA signature
98      * The standard by default uses SHA1 in a PKCS1 encoding.
99      *
100      * @param hashBuf Buffer containing the pre-calculated (binary) digest
101      * @param hashLen Length of the data in the digest buffer
102      * @param base64Signature Buffer containing the Base64 encoded signature
103      * @param sigLen Length of the data in the signature buffer
104      * @param type The hash method that was used to create the hash that is being
105      * passed in
106      * @returns true if the signature was valid, false otherwise
107      */
108 
109     virtual bool verifySHA1PKCS1Base64Signature(const unsigned char* hashBuf,
110                                  unsigned int hashLen,
111                                  const char* base64Signature,
112                                  unsigned int sigLen,
113                                  XSECCryptoHash::HashType type) const;
114 
115     /**
116      * \brief Create a signature
117      *
118      * The library will call this function to create a signature from
119      * a pre-calculated digest.  The output signature will
120      * be Base64 encoded such that it can be placed directly into the
121      * XML document
122      *
123      * @param hashBuf Buffer containing the pre-calculated (binary) digest
124      * @param hashLen Number of bytes of hash in the hashBuf
125      * @param base64SignatureBuf Buffer to place the base64 encoded result
126      * in.
127      * @param base64SignatureBufLen Implementations need to ensure they do
128      * not write more bytes than this into the buffer
129      * @param type Hash Method used in order to embed correct OID for sig
130      */
131 
132     virtual unsigned int signSHA1PKCS1Base64Signature(unsigned char* hashBuf,
133         unsigned int hashLen,
134         char* base64SignatureBuf,
135         unsigned int base64SignatureBufLen,
136         XSECCryptoHash::HashType type) const;
137 
138     /**
139      * \brief Decrypt using private key
140      *
141      * The library will call this function to decrypt a piece of cipher
142      * text using the private component of this key.
143      *
144      * @param inBuf cipher text to decrypt
145      * @param plainBuf output buffer for decrypted bytes
146      * @param inLength bytes of cipher text to decrypt
147      * @param maxOutLength size of outputBuffer
148      * @param padding Type of padding (PKCS 1.5 or OAEP)
149      * @param hashURI Hash Method for OAEP encryption
150      * @param mgfURI algorithm identifier for OAEP mask generation function
151      * @param params raw OAEP parameter data, if any
152      * @param paramslen OEP parameter length
153      */
154 
155     virtual unsigned int privateDecrypt(const unsigned char* inBuf,
156                                  unsigned char* plainBuf,
157                                  unsigned int inLength,
158                                  unsigned int maxOutLength,
159                                  PaddingType padding,
160                                  const XMLCh* hashURI=NULL,
161                                  const XMLCh* mgfURI=NULL,
162                                  unsigned char* params=NULL,
163                                  unsigned int paramsLen=0) const;
164 
165 
166     /**
167      * \brief Encrypt using a public key
168      *
169      * The library will call this function to encrypt a plain text buffer
170      * using the public component of this key.
171      *
172      * @param inBuf plain text to decrypt
173      * @param cipherBuf output buffer for decrypted bytes
174      * @param inLength bytes of plain text to encrypt
175      * @param maxOutLength size of outputBuffer
176      * @param padding Type of padding (PKCS 1.5 or OAEP)
177      * @param hashURI Hash Method for OAEP encryption
178      * @param mgfURI algorithm identifier for OAEP mask generation function
179      * @param params raw OAEP parameter data, if any
180      * @param paramslen OEP parameter length
181      */
182 
183     virtual unsigned int publicEncrypt(const unsigned char* inBuf,
184                                  unsigned char* cipherBuf,
185                                  unsigned int inLength,
186                                  unsigned int maxOutLength,
187                                  PaddingType padding,
188                                  const XMLCh* hashURI=NULL,
189                                  const XMLCh* mgfURI=NULL,
190                                  unsigned char* params=NULL,
191                                  unsigned int paramsLen=0) const;
192 
193     /**
194      * \brief Obtain the length of an RSA key
195      *
196      * @returns The length of the rsa key (in bytes)
197      */
198 
199     virtual unsigned int getLength() const;
200 
201     //@}
202 
203     /** @name Optional Interface methods
204      *
205      * Have been implemented to allow interoperability testing
206      */
207 
208     //@{
209 
210     /**
211      * \brief Load the modulus
212      *
213      * Load the modulus from a Base64 encoded string
214      *
215      * param b64 A buffer containing the encoded string
216      * param len The length of the data in the buffer
217      */
218 
219     virtual void loadPublicModulusBase64BigNums(const char* b64, unsigned int len);
220 
221     /**
222      * \brief Load the exponent
223      *
224      * Load the exponent from a Base64 encoded string
225      *
226      * param b64 A buffer containing the encoded string
227      * param len The length of the data in the buffer
228      */
229 
230     virtual void loadPublicExponentBase64BigNums(const char* b64, unsigned int len);
231 
232     //@}
233 
234     /** @name OpenSSL specific methods */
235     //@{
236 
237     /**
238      * \brief Constructor to create the object around an existing OpenSSL RSA
239      * key
240      *
241      * @param k The key to copy
242      * @note The object takes a copy of the original key, and will not delete k on
243      * completion.  This must be done by the caller.
244      */
245 
246     OpenSSLCryptoKeyRSA(EVP_PKEY* k);
247 
248     /**
249      * \brief Get OpenSSL RSA Object
250      */
251 
getOpenSSLRSA()252     RSA* getOpenSSLRSA() {return mp_rsaKey;}
253 
254     /**
255      * \brief Get OpenSSL RSA Object
256      */
257 
getOpenSSLRSA() const258     const RSA* getOpenSSLRSA() const {return mp_rsaKey;}
259 
260     //@}
261 
262 private:
263 
264     RSA* mp_rsaKey;
265 
266     BIGNUM *mp_accumE, *mp_accumN;
267     void setEBase(BIGNUM *eBase);
268     void setNBase(BIGNUM *nBase);
269 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
270     void commitEN();
271 #endif
272 
273 };
274 
275 #endif /* XSEC_HAVE_OPENSSL */
276 #endif /* OPENSSLCRYPTOKEYRSA_INCLUDE */
277