Google APIs Client Library for C++
openssl_codec.h
Go to the documentation of this file.
00001 /*
00002  * \copyright Copyright 2013 Google Inc. All Rights Reserved.
00003  * \license @{
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  *
00017  * @}
00018  */
00019 
00020 
00021 #ifndef APISERVING_CLIENTS_CPP_DATA_OPENSSL_CODEC_H_
00022 #define APISERVING_CLIENTS_CPP_DATA_OPENSSL_CODEC_H_
00023 
00024 #include <string>
00025 using std::string;
00026 #include "googleapis/client/data/codec.h"
00027 #include <glog/logging.h>
00028 #include "googleapis/base/macros.h"
00029 #include "googleapis/strings/stringpiece.h"
00030 #include <openssl/ossl_typ.h>
00031 #include "googleapis/util/status.h"
00032 namespace googleapis {
00033 
00034 namespace client {
00035 
00036 /*
00037  * Provdes a codec for encrypting and decrypting reader streams using OpenSSL.
00038  * @ingroup DataLayerCodec
00039  *
00040  * @see OpenSslCodecFactory
00041  */
00042 class OpenSslCodec : public Codec {
00043  public:
00044   /*
00045    * Standard constructor.
00046    * @see Init
00047    */
00048   OpenSslCodec();
00049 
00050   /*
00051    * Standard destructor.
00052    */
00053   virtual ~OpenSslCodec();
00054 
00055   /*
00056    * Sets the chunk size to use when encoding/decoding.
00057    *
00058    * @param[in] chunk_size Must be > 0
00059    *                       and should be a multiple of the cipher block size.
00060    *
00061    * There is probably no need for changing this, but helps testing.
00062    */
00063   void set_chunk_size(int chunk_size) {
00064     CHECK_LT(0, chunk_size_);
00065     chunk_size_ = chunk_size;
00066   }
00067 
00068   /*
00069    * Initializes with the cipher type, key, and initialization vector.
00070    *
00071    * @param[in] cipher_type  OpenSsl cipher type.
00072    * @param[in] key          The cipher key.
00073    * @param[in] iv           The cipher initialization vector.
00074    * @return ok or reason for failure.
00075    */
00076   util::Status Init(
00077        const EVP_CIPHER* cipher_type, const string& key, const string& iv);
00078 
00079   /*
00080    * Returns a reader that will encode another reader using this codec.
00081    *
00082    * @param[in] reader The caller maintain ownership.
00083    * @param[in] deleter The managed deleter may be used to delete the
00084    *                    reader. NULL indicates an unmanaged reader.
00085    * @param[out] status Will indicate ok or reason for failure.
00086    *
00087    * @return The reader may be an InvalidDataReader on failure but will
00088    *         not be NULL.
00089    */
00090   virtual DataReader* NewManagedEncodingReader(
00091       DataReader* reader, Closure* deleter, util::Status* status);
00092 
00093   /*
00094    * Returns a reader that will decode another reader using this codec.
00095    *
00096    * @param[in] reader The caller maintain ownership.
00097    * @param[in] deleter The managed deleter may be used to delete the
00098    *                    reader. NULL indicates an unmanaged reader.
00099    * @param[out] status Will indicate ok or reason for failure.
00100    *
00101    * @return The reader may be an InvalidDataReader on failure but will
00102    *         not be NULL.
00103    */
00104   virtual DataReader* NewManagedDecodingReader(
00105       DataReader* reader, Closure* deleter, util::Status* status);
00106 
00107  private:
00108   const EVP_CIPHER* cipher_type_;
00109   string key_;
00110   string iv_;
00111   int chunk_size_;
00112 
00113   DISALLOW_COPY_AND_ASSIGN(OpenSslCodec);
00114 };
00115 
00116 /*
00117  * CodecFactory for creating and configuring OpenSslCodecs.
00118  * @ingroup DataLayerCodec
00119  *
00120  * To configure creted ciphers, set the type, md, and aalt.
00121  */
00122 class OpenSslCodecFactory : public CodecFactory {
00123  public:
00124   /*
00125    * Standard constructor.
00126    */
00127   OpenSslCodecFactory();
00128 
00129   /*
00130    * Standard destructor.
00131    */
00132   ~OpenSslCodecFactory();
00133 
00134   /*
00135    * Sets the cipher_type for new codecs.
00136    *
00137    * This interface does not currently provide access to EVP_CIPHER_CTX_ctrl
00138    * so RC5 and RC2 might not be viable options without further enhacement.
00139    *
00140    * @param[in] type The OpenSsl cipher type.
00141    */
00142   void set_cipher_type(const EVP_CIPHER* type) { cipher_type_ = type; }
00143 
00144   /*
00145    * Sets the message digest algorithm for new codecs.
00146    *
00147    * @param[in] md The OpenSsl message digest algorithm.
00148    */
00149   void set_md(EVP_MD* md) { md_ = md; }
00150 
00151   /*
00152    * Sets the salt value to configure the algorithms with.
00153    *
00154    * @param[in] data The salt value to use should be exactly 8 bytes.
00155    */
00156   void set_salt(const StringPiece& data) { salt_ = data.as_string(); }
00157 
00158   /*
00159    * Sets the chunk size to use when encoding/decoding.
00160    *
00161    * @param[in] chunk_size Must be > 0
00162    *                       and should be a multiple of the cipher block size.
00163    *
00164    * There is probably no need for changing this, but helps testing.
00165    */
00166   void set_chunk_size(int chunk_size) {
00167     CHECK_LT(0, chunk_size_);
00168     chunk_size_ = chunk_size;
00169   }
00170 
00171   /*
00172    * Computes the key and initialization vector from a passphrase.
00173    *
00174    * @param[in] passphrase The passphrase to use.
00175    * @return ok or reason for failure.
00176    */
00177   util::Status SetPassphrase(const StringPiece& passphrase);
00178 
00179   /*
00180    * Constructs and configures a new codec instance.
00181    *
00182    * @param[out] status ok or reason for failure.
00183    * @return NULL on failure.
00184    */
00185   virtual Codec* New(util::Status* status);
00186 
00187 
00188  private:
00189   const EVP_CIPHER* cipher_type_;
00190   const EVP_MD* md_;
00191   string key_;
00192   string iv_;
00193   string salt_;
00194   int chunk_size_;
00195   int iterations_;
00196 
00197   DISALLOW_COPY_AND_ASSIGN(OpenSslCodecFactory);
00198 };
00199 
00200 }  // namespace client
00201 
00202 } // namespace googleapis
00203 #endif  // APISERVING_CLIENTS_CPP_DATA_OPENSSL_CODEC_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines