|
reSIProcate/stack
9694
|
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 */
1.7.5.1