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