reSIProcate/stack  9694
Security.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_SECURITY_HXX)
00002 #define RESIP_SECURITY_HXX
00003 
00004 #include <map>
00005 #include <vector>
00006 #include <list>
00007 
00008 #if defined(HAVE_CONFIG_H)
00009   #include "config.h"
00010 #endif
00011 
00012 
00013 #include "rutil/Socket.hxx"
00014 #include "rutil/BaseException.hxx"
00015 #include "resip/stack/SecurityTypes.hxx"
00016 #include "resip/stack/SecurityAttributes.hxx"
00017 
00018 // If USE_SSL is not defined, Security will not be built, and this header will 
00019 // not be installed. If you are including this file from a source tree, and are 
00020 // getting link errors, the source tree was probably built without USE_SSL.
00021 //#if defined(USE_SSL)
00022 //#else
00024 //typedef void BIO;
00025 //typedef void SSL;
00026 //typedef void X509;
00027 //typedef void X509_STORE;
00028 //typedef void SSL_CTX;
00029 //typedef void EVP_PKEY;
00030 //#endif
00031 
00032 #include <openssl/ssl.h>
00033 
00034 namespace resip
00035 {
00036 
00037 class Contents;
00038 class Pkcs7Contents;
00039 class Security;
00040 class MultipartSignedContents;
00041 class SipMessage;
00042 
00043 
00044 class BaseSecurity
00045 {
00046    public:
00047       class Exception : public BaseException
00048       {
00049          public:
00050             Exception(const Data& msg, const Data& file, const int line);
00051             const char* name() const { return "SecurityException"; }
00052       };
00053 
00054       class CipherList
00055       {
00056          public:
00057             CipherList(){}
00058             CipherList(const Data& cipherList) : mCipherList(cipherList) {}            
00059             Data cipherList() const { return mCipherList; }
00060          private:
00061             Data mCipherList;
00062       };
00063 
00064       public:
00065 
00066       typedef enum 
00067       {
00068          SubjectAltName,
00069          CommonName
00070       }NameType;
00071 
00072       struct PeerName
00073       {
00074          NameType mType;
00075          Data mName;
00076          PeerName(NameType type, Data name): mType(type), mName(name){}
00077       };
00078       
00079       static CipherList ExportableSuite;
00080       static CipherList StrongestSuite;
00081       
00082       BaseSecurity(const CipherList& cipherSuite = ExportableSuite);
00083       virtual ~BaseSecurity();
00084 
00085       // used to initialize the openssl library
00086       static void initialize();
00087 
00088       typedef enum
00089       {
00090          RootCert=1,
00091          DomainCert,
00092          DomainPrivateKey,
00093          UserCert,
00094          UserPrivateKey
00095       } PEMType;
00096 
00097       virtual void preload()=0;
00098 
00099       // name refers to the domainname or username which could be converted to a
00100       // filename by convention
00101       virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const =0;
00102       virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const =0;
00103       virtual void onRemovePEM(const Data& name, PEMType type) const =0;
00104 
00105       struct CertificateInfo
00106       {
00107             Data name;
00108             Data fingerprint;
00109             Data validFrom;
00110             Data validTo;
00111       };
00112 
00113       typedef std::vector<CertificateInfo> CertificateInfoContainer;
00114       CertificateInfoContainer getRootCertDescriptions() const;
00115 
00116       // All of these guys can throw SecurityException
00117 
00118       void addRootCertPEM(const Data& x509PEMEncodedRootCerts);
00119 
00120       void addDomainCertPEM(const Data& domainName, const Data& certPEM);
00121       void addDomainCertDER(const Data& domainName, const Data& certDER);
00122       bool hasDomainCert(const Data& domainName) const;
00123       void removeDomainCert(const Data& domainName);
00124       Data getDomainCertDER(const Data& domainName) const;
00125 
00126       void addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM);
00127       bool hasDomainPrivateKey(const Data& domainName) const;
00128       void removeDomainPrivateKey(const Data& domainName);
00129       Data getDomainPrivateKeyPEM(const Data& domainName) const;
00130 
00131       void addUserCertPEM(const Data& aor, const Data& certPEM);
00132       void addUserCertDER(const Data& aor, const Data& certDER);
00133       bool hasUserCert(const Data& aor) const;
00134       void removeUserCert(const Data& aor);
00135       Data getUserCertDER(const Data& aor) const;
00136 
00137       void setUserPassPhrase(const Data& aor, const Data& passPhrase);
00138       bool hasUserPassPhrase(const Data& aor) const;
00139       void removeUserPassPhrase(const Data& aor);
00140       Data getUserPassPhrase(const Data& aor) const;
00141 
00142       void addUserPrivateKeyPEM(const Data& aor, const Data& certPEM);
00143       void addUserPrivateKeyDER(const Data& aor, const Data& certDER);
00144       bool hasUserPrivateKey(const Data& aor) const;
00145       void removeUserPrivateKey(const Data& aor);
00146       Data getUserPrivateKeyPEM(const Data& aor) const;
00147       Data getUserPrivateKeyDER(const Data& aor) const;
00148 
00149       void generateUserCert(const Data& aor, int expireDays=365, int keyLen=1024);
00150 
00151       // Produces a detached signature
00152       MultipartSignedContents* sign(const Data& senderAor, Contents* );
00153       Pkcs7Contents* encrypt(Contents* , const Data& recipCertName );
00154       MultipartSignedContents* signAndEncrypt( const Data& senderAor, Contents* , const Data& recipCertName );
00155 
00156       Data computeIdentity( const Data& signerDomain, const Data& in ) const;
00157       bool checkIdentity( const Data& signerDomain, const Data& in, const Data& sig, X509* cert=NULL ) const;
00158 
00159       void checkAndSetIdentity(SipMessage& msg, const Data& derCert=Data::Empty ) const;
00160 
00161       // returns NULL if it fails
00162       Contents* decrypt( const Data& decryptorAor, const Pkcs7Contents* );
00163       
00164       // returns NULL if fails. returns the data that was originally signed
00165       Contents* checkSignature( MultipartSignedContents*, 
00166                                 Data* signedBy, SignatureStatus* sigStat );
00167       // returns the first SubjectAltName or commonName, if subjectAltName does not exist
00168       static Data getCertName(X509 *cert);
00169 
00170       // retrieves a list of all certificate names (subjectAltNAme's and CommonName)
00171       static void getCertNames(X509 *cert, std::list<PeerName> &peerNames, bool useEmailAsSIP = false);
00172 
00173       static bool isSelfSigned(const X509* cert);
00174 
00175       static int matchHostName(const Data& certificateName, const Data& domainName);
00176 
00177       // allow particular classes to acces the functions below 
00178       // friend class TlsConnection;
00179 
00180       // Allow overriding of RFC 5922 rules on certificate matching.
00181       static void setAllowWildcardCertificates(bool bEnable) { mAllowWildcardCertificates = bEnable; }
00182       static bool allowWildcardCertificates() { return mAllowWildcardCertificates; }
00183 
00184    public:
00185       SSL_CTX*       getTlsCtx ();
00186       SSL_CTX*       getSslCtx ();
00187       
00188       X509*     getDomainCert( const Data& domain );
00189       EVP_PKEY* getDomainKey(  const Data& domain );
00190       X509*     getUserCert(const Data& aor);
00191       EVP_PKEY* getUserPrivateKey(const Data& aor);
00192 
00193       // map of name to certificates
00194       typedef std::map<Data,X509*>     X509Map;
00195       typedef std::list<X509*>         X509List;
00196       typedef std::map<Data,EVP_PKEY*> PrivateKeyMap;
00197       typedef std::map<Data,Data>      PassPhraseMap;
00198 
00199    protected:
00200       SSL_CTX*       mTlsCtx;
00201       SSL_CTX*       mSslCtx;
00202       static void dumpAsn(char*, Data);
00203 
00204       CipherList mCipherList;
00205 
00206       // root cert list
00207       X509List       mRootCerts;
00208       X509_STORE*    mRootTlsCerts;
00209       X509_STORE*    mRootSslCerts;
00210 
00211       X509Map        mDomainCerts;
00212       PrivateKeyMap  mDomainPrivateKeys;
00213 
00214       X509Map        mUserCerts;
00215       PassPhraseMap  mUserPassPhrases;
00216       PrivateKeyMap  mUserPrivateKeys;
00217 
00218       void addCertPEM (PEMType type, const Data& name, const Data& certPEM, bool write);
00219       void addCertDER (PEMType type, const Data& name, const Data& certDER, bool write);
00220       bool hasCert    (PEMType type, const Data& name) const;
00221       void removeCert (PEMType type, const Data& name);
00222       Data getCertDER (PEMType type, const Data& name) const;
00223       void addCertX509(PEMType type, const Data& name, X509* cert, bool write);
00224 
00225       void addPrivateKeyPEM (PEMType type, const Data& name, const Data& privateKeyPEM, bool write);
00226       void addPrivateKeyDER (PEMType type, const Data& name, const Data& privateKeyDER, bool write);
00227       bool hasPrivateKey    (PEMType type, const Data& name) const;
00228       void removePrivateKey (PEMType type, const Data& name);
00229       Data getPrivateKeyPEM (PEMType type, const Data& name) const;
00230       Data getPrivateKeyDER (PEMType type, const Data& name) const;
00231       void addPrivateKeyPKEY(PEMType type, const Data& name, EVP_PKEY* pKey, bool write);
00232 
00233       // match with wildcards
00234       static int matchHostNameWithWildcards(const Data& certificateName, const Data& domainName);
00235       static bool mAllowWildcardCertificates;
00236 };
00237 
00238 class Security : public BaseSecurity
00239 {
00240    public:
00241       Security(const Data& pathToCerts, const CipherList& = ExportableSuite);
00242       Security(const CipherList& = ExportableSuite);
00243 
00244       void addCADirectory(const Data& caDirectory);
00245       void addCAFile(const Data& caFile);
00246 
00247       virtual void preload();
00248       virtual SSL_CTX* createDomainCtx(const SSL_METHOD* method, const Data& domain);
00249 
00250       virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const;
00251       virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const;
00252       virtual void onRemovePEM(const Data& name, PEMType type) const;
00253 
00254    private:
00255       Data mPath;
00256       std::list<Data> mCADirectories;
00257       std::list<Data> mCAFiles;
00258 };
00259 
00260 }
00261 
00262 #endif
00263 
00264 /* ====================================================================
00265  * The Vovida Software License, Version 1.0
00266  *
00267  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00268  *
00269  * Redistribution and use in source and binary forms, with or without
00270  * modification, are permitted provided that the following conditions
00271  * are met:
00272  *
00273  * 1. Redistributions of source code must retain the above copyright
00274  *    notice, this list of conditions and the following disclaimer.
00275  *
00276  * 2. Redistributions in binary form must reproduce the above copyright
00277  *    notice, this list of conditions and the following disclaimer in
00278  *    the documentation and/or other materials provided with the
00279  *    distribution.
00280  *
00281  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00282  *    and "Vovida Open Communication Application Library (VOCAL)" must
00283  *    not be used to endorse or promote products derived from this
00284  *    software without prior written permission. For written
00285  *    permission, please contact vocal@vovida.org.
00286  *
00287  * 4. Products derived from this software may not be called "VOCAL", nor
00288  *    may "VOCAL" appear in their name, without prior written
00289  *    permission of Vovida Networks, Inc.
00290  *
00291  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00292  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00293  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00294  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00295  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00296  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00297  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00298  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00299  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00300  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00301  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00302  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00303  * DAMAGE.
00304  *
00305  * ====================================================================
00306  *
00307  * This software consists of voluntary contributions made by Vovida
00308  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00309  * Inc.  For more information on Vovida Networks, Inc., please see
00310  * <http://www.vovida.org/>.
00311  *
00312  */