1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef OOX_HELPER_OPENSSL_WRAPPER_HXX
25 #define OOX_HELPER_OPENSSL_WRAPPER_HXX
26 
27 #include <sal/types.h>
28 #include "com/sun/star/uno/Exception.hpp"
29 
30 #include <openssl/evp.h>
31 #include <openssl/opensslv.h>
32 
33 namespace oox {
34 
35 // ============================================================================
36 
37 extern void throwOpenSSLException( const char *prefix ) throw ( ::com::sun::star::uno::Exception );
38 
39 
40 class OpenSSLDigest
41 {
42 public:
OpenSSLDigest()43     OpenSSLDigest() throw ( ::com::sun::star::uno::Exception )
44     {
45 #if OPENSSL_VERSION_NUMBER >= 0x10100000
46         digest_ctx = EVP_MD_CTX_new();
47 #else
48         digest_ctx = EVP_MD_CTX_create();
49 #endif
50         if( digest_ctx == NULL )
51             throwOpenSSLException( "Failed to create digest context" );
52     }
53 
~OpenSSLDigest()54     ~OpenSSLDigest()
55     {
56 #if OPENSSL_VERSION_NUMBER >= 0x10100000
57         EVP_MD_CTX_free( digest_ctx );
58 #else
59         EVP_MD_CTX_destroy( digest_ctx );
60 #endif
61     }
62 
initialize(const EVP_MD * aDigest)63     void initialize( const EVP_MD* aDigest ) throw ( ::com::sun::star::uno::Exception )
64     {
65         if( 1 != EVP_DigestInit_ex( digest_ctx, aDigest, NULL ) )
66             throwOpenSSLException( "Failed to initialize digest context" );
67         digest = aDigest;
68     }
69 
digestSize()70     int digestSize() throw ( ::com::sun::star::uno::Exception )
71     {
72         return digestSize( digest );
73     }
74 
update(const void * data,unsigned int count)75     void update( const void *data, unsigned int count ) throw ( ::com::sun::star::uno::Exception )
76     {
77         if( 1 != EVP_DigestUpdate( digest_ctx, data, count ) )
78             throwOpenSSLException( "Failed to update the digest context" );
79     }
80 
final(unsigned char * md,unsigned int * count)81     void final( unsigned char *md, unsigned int *count ) throw ( ::com::sun::star::uno::Exception )
82     {
83         if( 1 != EVP_DigestFinal_ex( digest_ctx, md, count ) )
84             throwOpenSSLException( "Failed to finalize digest" );
85     }
86 
digestSize(const EVP_MD * digest)87     static int digestSize( const EVP_MD* digest ) throw ( ::com::sun::star::uno::Exception )
88     {
89         int digest_size = EVP_MD_size( digest );
90         if( digest_size < 0 )
91             throwOpenSSLException( "Failed to get digest size" );
92         return digest_size;
93     }
94 
95 private:
96     OpenSSLDigest( const OpenSSLDigest& rValue );
97     OpenSSLDigest& operator=( const OpenSSLDigest& rValue );
98 
99     const EVP_MD*       digest;
100     EVP_MD_CTX*         digest_ctx;
101 };
102 
103 // ============================================================================
104 
105 class OpenSSLCipher
106 {
107 public:
OpenSSLCipher()108     OpenSSLCipher() throw ( ::com::sun::star::uno::Exception )
109     {
110         cipher_ctx = EVP_CIPHER_CTX_new();
111         if( cipher_ctx == NULL )
112             throwOpenSSLException( "Failed to create cipher context" );
113     }
114 
~OpenSSLCipher()115     ~OpenSSLCipher()
116     {
117         EVP_CIPHER_CTX_free( cipher_ctx );
118     }
119 
initialize(const EVP_CIPHER * aCipher,const unsigned char * key,const unsigned char * iv,int enc)120     void initialize( const EVP_CIPHER *aCipher, const unsigned char *key, const unsigned char *iv, int enc ) throw ( ::com::sun::star::uno::Exception )
121     {
122         if( 1 != EVP_CipherInit_ex( cipher_ctx, aCipher, NULL, key, iv, enc ) )
123             throwOpenSSLException( "Failed to initialize the cipher context for decryption" );
124         cipher = aCipher;
125     }
126 
setPadding(int padding)127     void setPadding( int padding) throw ( ::com::sun::star::uno::Exception )
128     {
129         if( 1 != EVP_CIPHER_CTX_set_padding( cipher_ctx, padding ) )
130             throwOpenSSLException( "Failed to set cipher padding" );
131     }
132 
update(const unsigned char * dataIn,int dataInSize,unsigned char * dataOut,int * dataOutSize)133     void update( const unsigned char* dataIn, int dataInSize, unsigned char *dataOut, int *dataOutSize ) throw ( ::com::sun::star::uno::Exception )
134     {
135         if( 1 != EVP_CipherUpdate( cipher_ctx, dataOut, dataOutSize, dataIn, dataInSize ) )
136             throwOpenSSLException( "EVP_CipherUpdate failed" );
137     }
138 
final(unsigned char * dataOut,int * dataOutSize)139     void final( unsigned char *dataOut, int *dataOutSize ) throw ( ::com::sun::star::uno::Exception )
140     {
141         if( 1 != EVP_CipherFinal( cipher_ctx, dataOut, dataOutSize ) )
142             throwOpenSSLException( "EVP_CipherFinal failed" );
143     }
144 
blockSize(const EVP_CIPHER * cipherAlgorithm)145     static int blockSize( const EVP_CIPHER *cipherAlgorithm )
146     {
147         return EVP_CIPHER_block_size( cipherAlgorithm );
148     }
149 
150 private:
151     OpenSSLCipher( const OpenSSLCipher& rValue );
152     OpenSSLCipher& operator=( const OpenSSLCipher& rValue );
153 
154     EVP_CIPHER_CTX*     cipher_ctx;
155     const EVP_CIPHER*   cipher;
156 };
157 
158 // ============================================================================
159 
160 } // namespace oox
161 
162 #endif
163