1 /* 2 * pssl.h 3 * 4 * Secure Sockets Layer channel interface class. 5 * 6 * Portable Windows Library 7 * 8 * Copyright (c) 1993-2002 Equivalence Pty. Ltd. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * The Original Code is Portable Windows Library. 21 * 22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 23 * 24 * Contributor(s): ______________________________________. 25 * 26 * $Revision: 25519 $ 27 * $Author: rjongbloed $ 28 * $Date: 2011-04-06 03:26:18 -0500 (Wed, 06 Apr 2011) $ 29 */ 30 31 #ifndef PTLIB_PSSL_H 32 #define PTLIB_PSSL_H 33 34 #ifdef P_USE_PRAGMA 35 #pragma interface 36 #endif 37 38 #include <ptlib/sockets.h> 39 40 41 struct ssl_st; 42 struct ssl_ctx_st; 43 struct x509_st; 44 struct evp_pkey_st; 45 struct dh_st; 46 47 enum PSSLFileTypes { 48 PSSLFileTypePEM, 49 PSSLFileTypeASN1, 50 PSSLFileTypeDEFAULT 51 }; 52 53 54 /**Private key for SSL. 55 This class embodies a common environment for all private keys used by the 56 PSSLContext and PSSLChannel classes. 57 */ 58 class PSSLPrivateKey : public PObject 59 { 60 PCLASSINFO(PSSLPrivateKey, PObject); 61 public: 62 /**Create an empty private key. 63 */ 64 PSSLPrivateKey(); 65 66 /**Create a new RSA private key. 67 */ 68 PSSLPrivateKey( 69 unsigned modulus, ///< Number of bits 70 void (*callback)(int,int,void *) = NULL, ///< Progress callback function 71 void *cb_arg = NULL ///< Argument passed to callback 72 ); 73 74 /**Create a new private key given the file. 75 The type of the private key can be specified explicitly, or if 76 PSSLFileTypeDEFAULT it will be determined from the file extension, 77 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 78 */ 79 PSSLPrivateKey( 80 const PFilePath & keyFile, ///< Private key file 81 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 82 ); 83 84 /**Create private key from the binary ASN1 DER encoded data specified. 85 */ 86 PSSLPrivateKey( 87 const BYTE * keyData, ///< Private key data 88 PINDEX keySize ///< Size of private key data 89 ); 90 91 /**Create private key from the binary ASN1 DER encoded data specified. 92 */ 93 PSSLPrivateKey( 94 const PBYTEArray & keyData ///< Private key data 95 ); 96 97 /**Create a copy of the private key. 98 */ 99 PSSLPrivateKey( 100 const PSSLPrivateKey & privKey 101 ); 102 103 /**Create a copy of the private key. 104 */ 105 PSSLPrivateKey & operator=( 106 const PSSLPrivateKey & privKay 107 ); 108 109 /**Destroy and release storage for private key. 110 */ 111 ~PSSLPrivateKey(); 112 113 /**Get internal OpenSSL private key structure. 114 */ 115 operator evp_pkey_st *() const { return key; } 116 117 /**Create a new private key. 118 */ 119 PBoolean Create( 120 unsigned modulus, ///< Number of bits 121 void (*callback)(int,int,void *) = NULL, ///< Progress callback function 122 void *cb_arg = NULL ///< Argument passed to callback 123 ); 124 125 /**Get the certificate as binary ASN1 DER encoded data. 126 */ 127 PBYTEArray GetData() const; 128 129 /**Get the certificate as ASN1 DER base64 encoded data. 130 */ 131 PString AsString() const; 132 133 /**Load private key from file. 134 The type of the private key can be specified explicitly, or if 135 PSSLFileTypeDEFAULT it will be determined from the file extension, 136 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 137 */ 138 PBoolean Load( 139 const PFilePath & keyFile, ///< Private key file 140 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 141 ); 142 143 /**Save private key to file. 144 The type of the private key can be specified explicitly, or if 145 PSSLFileTypeDEFAULT it will be determined from the file extension, 146 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 147 */ 148 PBoolean Save( 149 const PFilePath & keyFile, ///< Private key file 150 PBoolean append = false, ///< Append to file 151 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to write 152 ); 153 154 155 protected: 156 evp_pkey_st * key; 157 }; 158 159 160 /**Certificate for SSL. 161 This class embodies a common environment for all certificates used by the 162 PSSLContext and PSSLChannel classes. 163 */ 164 class PSSLCertificate : public PObject 165 { 166 PCLASSINFO(PSSLCertificate, PObject); 167 public: 168 /**Create an empty certificate. 169 */ 170 PSSLCertificate(); 171 172 /**Create a new certificate given the file. 173 The type of the certificate key can be specified explicitly, or if 174 PSSLFileTypeDEFAULT it will be determined from the file extension, 175 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 176 */ 177 PSSLCertificate( 178 const PFilePath & certFile, ///< Certificate file 179 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 180 ); 181 182 /**Create certificate from the binary ASN1 DER encoded data specified. 183 */ 184 PSSLCertificate( 185 const BYTE * certData, ///< Certificate data 186 PINDEX certSize ///< Size of certificate data 187 ); 188 189 /**Create certificate from the binary ASN1 DER encoded data specified. 190 */ 191 PSSLCertificate( 192 const PBYTEArray & certData ///< Certificate data 193 ); 194 195 /**Create certificate from the ASN1 DER base64 encoded data specified. 196 */ 197 PSSLCertificate( 198 const PString & certString ///< Certificate data as string 199 ); 200 201 /**Create a copy of the certificate. 202 */ 203 PSSLCertificate( 204 const PSSLCertificate & cert 205 ); 206 207 /**Create a copy of the certificate. 208 */ 209 PSSLCertificate & operator=( 210 const PSSLCertificate & cert 211 ); 212 213 /**Destroy and release storage for certificate. 214 */ 215 ~PSSLCertificate(); 216 217 /**Get internal OpenSSL X509 structure. 218 */ 219 operator x509_st *() const { return certificate; } 220 221 /**Create a new root certificate. 222 The subject name is a string of the form "/name=value/name=value" where 223 name is a short name for the field and value is a string value for the 224 field for example: 225 "/C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc" 226 "/OU=Certification Services Division/CN=Thawte Server CA" 227 "/Email=server-certs@thawte.com" 228 */ 229 PBoolean CreateRoot( 230 const PString & subject, ///< Subject name for certificate 231 const PSSLPrivateKey & key ///< Key to sign certificate with 232 ); 233 234 /**Get the certificate as binary ASN1 DER encoded data. 235 */ 236 PBYTEArray GetData() const; 237 238 /**Get the certificate as ASN1 DER base64 encoded data. 239 */ 240 PString AsString() const; 241 242 /**Load certificate from file. 243 The type of the certificate key can be specified explicitly, or if 244 PSSLFileTypeDEFAULT it will be determined from the file extension, 245 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 246 */ 247 PBoolean Load( 248 const PFilePath & certFile, ///< Certificate file 249 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 250 ); 251 252 /**Save certificate to file. 253 The type of the certificate key can be specified explicitly, or if 254 PSSLFileTypeDEFAULT it will be determined from the file extension, 255 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 256 */ 257 PBoolean Save( 258 const PFilePath & keyFile, ///< Certificate key file 259 PBoolean append = false, ///< Append to file 260 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to write 261 ); 262 263 264 protected: 265 x509_st * certificate; 266 }; 267 268 269 /**Diffie-Hellman parameters for SSL. 270 This class embodies a set of Diffie Helman parameters as used by 271 PSSLContext and PSSLChannel classes. 272 */ 273 class PSSLDiffieHellman : public PObject 274 { 275 PCLASSINFO(PSSLDiffieHellman, PObject); 276 public: 277 /**Create an empty set of Diffie-Hellman parameters. 278 */ 279 PSSLDiffieHellman(); 280 281 /**Create a new set of Diffie-Hellman parameters given the file. 282 The type of the file can be specified explicitly, or if 283 PSSLFileTypeDEFAULT it will be determined from the file extension, 284 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 285 */ 286 PSSLDiffieHellman( 287 const PFilePath & dhFile, ///< Diffie-Hellman parameters file 288 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 289 ); 290 291 /**Create a set of Diffie-Hellman parameters. 292 */ 293 PSSLDiffieHellman( 294 const BYTE * pData, ///< P data 295 PINDEX pSize, ///< Size of P data 296 const BYTE * gData, ///< G data 297 PINDEX gSize ///< Size of G data 298 ); 299 300 /**Create a copy of the Diffie-Hellman parameters. 301 */ 302 PSSLDiffieHellman( 303 const PSSLDiffieHellman & dh 304 ); 305 306 /**Create a copy of the Diffie-Hellman parameters. 307 */ 308 PSSLDiffieHellman & operator=( 309 const PSSLDiffieHellman & dh 310 ); 311 312 /**Destroy and release storage for Diffie-Hellman parameters. 313 */ 314 ~PSSLDiffieHellman(); 315 316 /**Get internal OpenSSL DH structure. 317 */ 318 operator dh_st *() const { return dh; } 319 320 /**Load Diffie-Hellman parameters from file. 321 The type of the file can be specified explicitly, or if 322 PSSLFileTypeDEFAULT it will be determined from the file extension, 323 ".pem" is a text file, anything else eg ".der" is a binary ASN1 file. 324 */ 325 PBoolean Load( 326 const PFilePath & dhFile, ///< Diffie-Hellman parameters file 327 PSSLFileTypes fileType = PSSLFileTypeDEFAULT ///< Type of file to read 328 ); 329 330 protected: 331 dh_st * dh; 332 }; 333 334 335 /**Context for SSL channels. 336 This class embodies a common environment for all connections made via SSL 337 using the PSSLChannel class. It includes such things as the version of SSL 338 and certificates, CA's etc. 339 */ 340 class PSSLContext { 341 public: 342 enum Method { 343 SSLv23, 344 SSLv3, 345 TLSv1 346 }; 347 348 /**Create a new context for SSL channels. 349 An optional session ID may be provided in the context. This is used 350 to identify sessions across multiple channels in this context. The 351 session ID is a completely arbitrary block of data. If sessionId is 352 non NULL and idSize is zero, then sessionId is assumed to be a pointer 353 to a C string. 354 The default SSL method is SSLv23 355 */ 356 PSSLContext( 357 const void * sessionId = NULL, ///< Pointer to session ID 358 PINDEX idSize = 0 ///< Size of session ID 359 ); 360 PSSLContext( 361 Method method, ///< SSL connection method 362 const void * sessionId = NULL, ///< Pointer to session ID 363 PINDEX idSize = 0 ///< Size of session ID 364 ); 365 366 /**Clean up the SSL context. 367 */ 368 ~PSSLContext(); 369 370 /**Get the internal SSL context structure. 371 */ 372 operator ssl_ctx_st *() const { return context; } 373 374 /**Set the path to locate CA certificates. 375 */ 376 PBoolean SetCAPath( 377 const PDirectory & caPath ///< Directory for CA certificates 378 ); 379 380 /**Set the CA certificate file. 381 */ 382 PBoolean SetCAFile( 383 const PFilePath & caFile ///< CA certificate file 384 ); 385 386 /**Use the certificate specified. 387 */ 388 PBoolean UseCertificate( 389 const PSSLCertificate & certificate 390 ); 391 392 /**Use the private key specified. 393 */ 394 PBoolean UsePrivateKey( 395 const PSSLPrivateKey & key 396 ); 397 398 /**Use the Diffie-Hellman parameters specified. 399 */ 400 PBoolean UseDiffieHellman( 401 const PSSLDiffieHellman & dh 402 ); 403 404 /**Set the available ciphers to those listed. 405 */ 406 PBoolean SetCipherList( 407 const PString & ciphers ///< List of cipher names. 408 ); 409 410 protected: 411 void Construct(Method method, const void * sessionId, PINDEX idSize); 412 ssl_ctx_st * context; 413 }; 414 415 416 /**This class will start a secure SSL based channel. 417 */ 418 class PSSLChannel : public PIndirectChannel 419 { 420 PCLASSINFO(PSSLChannel, PIndirectChannel) 421 public: 422 /**Create a new channel given the context. 423 If no context is given a default one is created. 424 */ 425 PSSLChannel( 426 PSSLContext * context = NULL, ///< Context for SSL channel 427 PBoolean autoDeleteContext = false ///< Flag for context to be automatically deleted. 428 ); 429 PSSLChannel( 430 PSSLContext & context ///< Context for SSL channel 431 ); 432 433 /**Close and clear the SSL channel. 434 */ 435 ~PSSLChannel(); 436 437 // Overrides from PChannel 438 virtual PBoolean Read(void * buf, PINDEX len); 439 virtual PBoolean Write(const void * buf, PINDEX len); 440 virtual PBoolean Close(); Shutdown(ShutdownValue)441 virtual PBoolean Shutdown(ShutdownValue) { return true; } 442 virtual PString GetErrorText(ErrorGroup group = NumErrorGroups) const; 443 virtual PBoolean ConvertOSError(int error, ErrorGroup group = LastGeneralError); 444 445 // New functions 446 /**Accept a new inbound connection (server). 447 This version expects that the indirect channel has already been opened 448 using Open() beforehand. 449 */ 450 PBoolean Accept(); 451 452 /**Accept a new inbound connection (server). 453 */ 454 PBoolean Accept( 455 PChannel & channel ///< Channel to attach to. 456 ); 457 458 /**Accept a new inbound connection (server). 459 */ 460 PBoolean Accept( 461 PChannel * channel, ///< Channel to attach to. 462 PBoolean autoDelete = true ///< Flag for if channel should be automatically deleted. 463 ); 464 465 466 /**Connect to remote server. 467 This version expects that the indirect channel has already been opened 468 using Open() beforehand. 469 */ 470 PBoolean Connect(); 471 472 /**Connect to remote server. 473 */ 474 PBoolean Connect( 475 PChannel & channel ///< Channel to attach to. 476 ); 477 478 /**Connect to remote server. 479 */ 480 PBoolean Connect( 481 PChannel * channel, ///< Channel to attach to. 482 PBoolean autoDelete = true ///< Flag for if channel should be automatically deleted. 483 ); 484 485 /**Use the certificate specified. 486 */ 487 PBoolean UseCertificate( 488 const PSSLCertificate & certificate 489 ); 490 491 /**Use the private key file specified. 492 */ 493 PBoolean UsePrivateKey( 494 const PSSLPrivateKey & key 495 ); 496 497 enum VerifyMode { 498 VerifyNone, 499 VerifyPeer, 500 VerifyPeerMandatory, 501 }; 502 503 void SetVerifyMode( 504 VerifyMode mode 505 ); 506 GetContext()507 PSSLContext * GetContext() const { return context; } 508 509 virtual PBoolean RawSSLRead(void * buf, PINDEX & len); 510 511 protected: 512 /**This callback is executed when the Open() function is called with 513 open channels. It may be used by descendent channels to do any 514 handshaking required by the protocol that channel embodies. 515 516 The default behaviour "connects" the channel to the OpenSSL library. 517 518 @return 519 Returns true if the protocol handshaking is successful. 520 */ 521 virtual PBoolean OnOpen(); 522 523 protected: 524 PSSLContext * context; 525 PBoolean autoDeleteContext; 526 ssl_st * ssl; 527 }; 528 529 #endif // PTLIB_PSSL_H 530 531 532 // End Of File /////////////////////////////////////////////////////////////// 533