├── .gitignore ├── Packages ├── 10.1Berlin │ ├── OpenSSL.dpk │ ├── OpenSSL.dproj │ └── OpenSSL.res ├── 10.2Tokyo │ ├── OpenSSL.dpk │ ├── OpenSSL.dproj │ └── OpenSSL.res ├── 10.3Rio │ ├── OpenSSL.dpk │ ├── OpenSSL.dproj │ └── OpenSSL.res └── XE7 │ ├── OpenSSL.dpk │ ├── OpenSSL.dproj │ └── OpenSSL.res ├── README.md ├── Samples └── SSLDemo │ ├── SSLDemo.EncFrame.dfm │ ├── SSLDemo.EncFrame.pas │ ├── SSLDemo.KeyPairFrame.dfm │ ├── SSLDemo.KeyPairFrame.pas │ ├── SSLDemo.MainForm.dfm │ ├── SSLDemo.MainForm.pas │ ├── SSLDemo.MainFrame.dfm │ ├── SSLDemo.MainFrame.pas │ ├── SSLDemo.RSABufferFrame.dfm │ ├── SSLDemo.RSABufferFrame.pas │ ├── SSLDemo.RandFrame.dfm │ ├── SSLDemo.RandFrame.pas │ ├── SSLDemo.UnpackPKCS7Frame.dfm │ ├── SSLDemo.UnpackPKCS7Frame.pas │ ├── SSLDemo.dpr │ ├── SSLDemo.dproj │ └── SSLDemo.res ├── Source ├── OpenSSL.Core.pas ├── OpenSSL.EncUtils.pas ├── OpenSSL.RSAUtils.pas ├── OpenSSL.RandUtils.pas ├── OpenSSL.SMIMEUtils.pas └── OpenSSL.libeay32.pas └── TestData ├── TestPKCS7.pdf ├── create_cert.bat ├── create_cert_pwd.bat └── create_p7m.bat /.gitignore: -------------------------------------------------------------------------------- 1 | /Lib 2 | *.dcu 3 | *.local 4 | *.exe 5 | *.identcache 6 | __history 7 | *.~* 8 | *.map 9 | *.stat 10 | TestData/.rnd 11 | *.pem 12 | *.txt 13 | *.certcry 14 | *.keycry 15 | .rnd 16 | TestData/*.cnf 17 | TestData/*.p7m 18 | TestData/TestPKCS7-out.pdf 19 | -------------------------------------------------------------------------------- /Packages/10.1Berlin/OpenSSL.dpk: -------------------------------------------------------------------------------- 1 | package OpenSSL; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$DESCRIPTION 'Delphi OpenSSL Wrapper'} 29 | {$LIBSUFFIX '240'} 30 | {$IMPLICITBUILD OFF} 31 | 32 | requires 33 | rtl, 34 | IndySystem, 35 | IndyProtocols, 36 | IndyCore; 37 | 38 | contains 39 | OpenSSL.Core in '..\..\Source\OpenSSL.Core.pas', 40 | OpenSSL.EncUtils in '..\..\Source\OpenSSL.EncUtils.pas', 41 | OpenSSL.libeay32 in '..\..\Source\OpenSSL.libeay32.pas', 42 | OpenSSL.RandUtils in '..\..\Source\OpenSSL.RandUtils.pas', 43 | OpenSSL.RSAUtils in '..\..\Source\OpenSSL.RSAUtils.pas', 44 | OpenSSL.SMIMEUtils in '..\..\Source\OpenSSL.SMIMEUtils.pas'; 45 | 46 | end. 47 | -------------------------------------------------------------------------------- /Packages/10.1Berlin/OpenSSL.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {4D944443-DB16-471B-BCD5-AE06947E67E3} 4 | OpenSSL.dpk 5 | 18.2 6 | None 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Package 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Cfg_1 29 | true 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Delphi OpenSSL Wrapper 40 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 41 | 1040 42 | OpenSSL 43 | 240 44 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 45 | true 46 | true 47 | ../../Lib/$(DLLSUFFIX)/$(Platform)/$(Config) 48 | .\$(Platform)\$(Config) 49 | false 50 | false 51 | false 52 | false 53 | false 54 | 55 | 56 | 1033 57 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 58 | true 59 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) 60 | 61 | 62 | DEBUG;$(DCC_Define) 63 | true 64 | false 65 | true 66 | true 67 | true 68 | 69 | 70 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 71 | 1033 72 | true 73 | false 74 | 75 | 76 | false 77 | RELEASE;$(DCC_Define) 78 | 0 79 | 0 80 | 81 | 82 | 83 | MainSource 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Cfg_2 97 | Base 98 | 99 | 100 | Base 101 | 102 | 103 | Cfg_1 104 | Base 105 | 106 | 107 | 108 | Delphi.Personality.12 109 | Package 110 | 111 | 112 | 113 | OpenSSL.dpk 114 | 115 | 116 | Microsoft Office 2000 Sample Automation Server Wrapper Components 117 | Microsoft Office XP Sample Automation Server Wrapper Components 118 | 119 | 120 | 121 | 122 | 123 | OpenSSL.bpl 124 | true 125 | 126 | 127 | 128 | 129 | OpenSSL.bpl 130 | true 131 | 132 | 133 | 134 | 135 | true 136 | 137 | 138 | 139 | 140 | true 141 | 142 | 143 | 144 | 145 | true 146 | 147 | 148 | 149 | 150 | true 151 | 152 | 153 | 154 | 155 | 0 156 | .dll;.bpl 157 | 158 | 159 | 1 160 | .dylib 161 | 162 | 163 | 164 | 165 | Contents\Resources 166 | 1 167 | 168 | 169 | 170 | 171 | classes 172 | 1 173 | 174 | 175 | 176 | 177 | res\drawable-xxhdpi 178 | 1 179 | 180 | 181 | 182 | 183 | Contents\MacOS 184 | 0 185 | 186 | 187 | 1 188 | 189 | 190 | 191 | 192 | library\lib\mips 193 | 1 194 | 195 | 196 | 197 | 198 | 1 199 | 200 | 201 | 1 202 | 203 | 204 | 1 205 | 206 | 207 | 208 | 209 | 1 210 | 211 | 212 | 1 213 | 214 | 215 | 0 216 | 217 | 218 | 1 219 | 220 | 221 | 1 222 | 223 | 224 | library\lib\armeabi-v7a 225 | 1 226 | 227 | 228 | 1 229 | 230 | 231 | 232 | 233 | 0 234 | 235 | 236 | 1 237 | .framework 238 | 239 | 240 | 241 | 242 | 1 243 | 244 | 245 | 1 246 | 247 | 248 | 249 | 250 | 1 251 | 252 | 253 | 1 254 | 255 | 256 | 1 257 | 258 | 259 | 260 | 261 | 262 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 263 | 1 264 | 265 | 266 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 267 | 1 268 | 269 | 270 | 271 | 272 | 1 273 | 274 | 275 | 1 276 | 277 | 278 | 1 279 | 280 | 281 | 282 | 283 | 1 284 | 285 | 286 | 1 287 | 288 | 289 | 1 290 | 291 | 292 | 293 | 294 | 295 | library\lib\armeabi 296 | 1 297 | 298 | 299 | 300 | 301 | 0 302 | 303 | 304 | 1 305 | 306 | 307 | 1 308 | 309 | 310 | 311 | 312 | 1 313 | 314 | 315 | 1 316 | 317 | 318 | 1 319 | 320 | 321 | 322 | 323 | res\drawable-normal 324 | 1 325 | 326 | 327 | 328 | 329 | res\drawable-xhdpi 330 | 1 331 | 332 | 333 | 334 | 335 | res\drawable-large 336 | 1 337 | 338 | 339 | 340 | 341 | 1 342 | 343 | 344 | 1 345 | 346 | 347 | 1 348 | 349 | 350 | 351 | 352 | Assets 353 | 1 354 | 355 | 356 | Assets 357 | 1 358 | 359 | 360 | 361 | 362 | 363 | library\lib\armeabi-v7a 364 | 1 365 | 366 | 367 | 368 | 369 | res\drawable-hdpi 370 | 1 371 | 372 | 373 | 374 | 375 | 376 | 377 | Assets 378 | 1 379 | 380 | 381 | Assets 382 | 1 383 | 384 | 385 | 386 | 387 | 1 388 | 389 | 390 | 1 391 | 392 | 393 | 1 394 | 395 | 396 | 397 | 398 | res\values 399 | 1 400 | 401 | 402 | 403 | 404 | res\drawable-small 405 | 1 406 | 407 | 408 | 409 | 410 | res\drawable 411 | 1 412 | 413 | 414 | 415 | 416 | 1 417 | 418 | 419 | 1 420 | 421 | 422 | 1 423 | 424 | 425 | 426 | 427 | 1 428 | 429 | 430 | 431 | 432 | res\drawable 433 | 1 434 | 435 | 436 | 437 | 438 | 0 439 | 440 | 441 | 0 442 | 443 | 444 | 0 445 | 446 | 447 | 0 448 | 449 | 450 | 0 451 | 452 | 453 | 0 454 | 455 | 456 | 457 | 458 | library\lib\armeabi-v7a 459 | 1 460 | 461 | 462 | 463 | 464 | 0 465 | .bpl 466 | 467 | 468 | 1 469 | .dylib 470 | 471 | 472 | 1 473 | .dylib 474 | 475 | 476 | 1 477 | .dylib 478 | 479 | 480 | 1 481 | .dylib 482 | 483 | 484 | 485 | 486 | res\drawable-mdpi 487 | 1 488 | 489 | 490 | 491 | 492 | res\drawable-xlarge 493 | 1 494 | 495 | 496 | 497 | 498 | res\drawable-ldpi 499 | 1 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | False 514 | True 515 | False 516 | 517 | 518 | 12 519 | 520 | 521 | 522 | 523 | 524 | -------------------------------------------------------------------------------- /Packages/10.1Berlin/OpenSSL.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/Packages/10.1Berlin/OpenSSL.res -------------------------------------------------------------------------------- /Packages/10.2Tokyo/OpenSSL.dpk: -------------------------------------------------------------------------------- 1 | package OpenSSL; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$DESCRIPTION 'Delphi OpenSSL Wrapper'} 29 | {$LIBSUFFIX '250'} 30 | {$IMPLICITBUILD OFF} 31 | 32 | requires 33 | rtl, 34 | IndySystem, 35 | IndyProtocols, 36 | IndyCore; 37 | 38 | contains 39 | OpenSSL.Core in '..\..\Source\OpenSSL.Core.pas', 40 | OpenSSL.EncUtils in '..\..\Source\OpenSSL.EncUtils.pas', 41 | OpenSSL.libeay32 in '..\..\Source\OpenSSL.libeay32.pas', 42 | OpenSSL.RandUtils in '..\..\Source\OpenSSL.RandUtils.pas', 43 | OpenSSL.RSAUtils in '..\..\Source\OpenSSL.RSAUtils.pas', 44 | OpenSSL.SMIMEUtils in '..\..\Source\OpenSSL.SMIMEUtils.pas'; 45 | 46 | end. 47 | -------------------------------------------------------------------------------- /Packages/10.2Tokyo/OpenSSL.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {4D944443-DB16-471B-BCD5-AE06947E67E3} 4 | OpenSSL.dpk 5 | 18.4 6 | None 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Package 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Cfg_1 29 | true 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | Delphi OpenSSL Wrapper 39 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 40 | 1040 41 | OpenSSL 42 | 250 43 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 44 | true 45 | true 46 | ../../Lib/$(DLLSUFFIX)/$(Platform)/$(Config) 47 | .\$(Platform)\$(Config) 48 | false 49 | false 50 | false 51 | false 52 | false 53 | true 54 | 55 | 56 | 1033 57 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 58 | true 59 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) 60 | 61 | 62 | DEBUG;$(DCC_Define) 63 | true 64 | false 65 | true 66 | true 67 | true 68 | 69 | 70 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 71 | 1033 72 | true 73 | false 74 | 75 | 76 | false 77 | RELEASE;$(DCC_Define) 78 | 0 79 | 0 80 | 81 | 82 | 83 | MainSource 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Cfg_2 97 | Base 98 | 99 | 100 | Base 101 | 102 | 103 | Cfg_1 104 | Base 105 | 106 | 107 | 108 | Delphi.Personality.12 109 | Package 110 | 111 | 112 | 113 | OpenSSL.dpk 114 | 115 | 116 | Microsoft Office 2000 Sample Automation Server Wrapper Components 117 | Microsoft Office XP Sample Automation Server Wrapper Components 118 | 119 | 120 | 121 | 122 | 123 | OpenSSL.bpl 124 | true 125 | 126 | 127 | 128 | 129 | OpenSSL.bpl 130 | true 131 | 132 | 133 | 134 | 135 | true 136 | 137 | 138 | 139 | 140 | true 141 | 142 | 143 | 144 | 145 | true 146 | 147 | 148 | 149 | 150 | true 151 | 152 | 153 | 154 | 155 | 1 156 | 157 | 158 | Contents\MacOS 159 | 0 160 | 161 | 162 | 163 | 164 | classes 165 | 1 166 | 167 | 168 | 169 | 170 | library\lib\armeabi-v7a 171 | 1 172 | 173 | 174 | 175 | 176 | library\lib\armeabi 177 | 1 178 | 179 | 180 | 181 | 182 | library\lib\mips 183 | 1 184 | 185 | 186 | 187 | 188 | 189 | library\lib\armeabi-v7a 190 | 1 191 | 192 | 193 | 194 | 195 | res\drawable 196 | 1 197 | 198 | 199 | 200 | 201 | res\values 202 | 1 203 | 204 | 205 | 206 | 207 | res\drawable 208 | 1 209 | 210 | 211 | 212 | 213 | res\drawable-xxhdpi 214 | 1 215 | 216 | 217 | 218 | 219 | res\drawable-ldpi 220 | 1 221 | 222 | 223 | 224 | 225 | res\drawable-mdpi 226 | 1 227 | 228 | 229 | 230 | 231 | res\drawable-hdpi 232 | 1 233 | 234 | 235 | 236 | 237 | res\drawable-xhdpi 238 | 1 239 | 240 | 241 | 242 | 243 | res\drawable-small 244 | 1 245 | 246 | 247 | 248 | 249 | res\drawable-normal 250 | 1 251 | 252 | 253 | 254 | 255 | res\drawable-large 256 | 1 257 | 258 | 259 | 260 | 261 | res\drawable-xlarge 262 | 1 263 | 264 | 265 | 266 | 267 | 1 268 | 269 | 270 | 1 271 | 272 | 273 | 0 274 | 275 | 276 | 277 | 278 | 1 279 | .framework 280 | 281 | 282 | 0 283 | 284 | 285 | 286 | 287 | 1 288 | .dylib 289 | 290 | 291 | 0 292 | .dll;.bpl 293 | 294 | 295 | 296 | 297 | 1 298 | .dylib 299 | 300 | 301 | 1 302 | .dylib 303 | 304 | 305 | 1 306 | .dylib 307 | 308 | 309 | 1 310 | .dylib 311 | 312 | 313 | 0 314 | .bpl 315 | 316 | 317 | 318 | 319 | 0 320 | 321 | 322 | 0 323 | 324 | 325 | 0 326 | 327 | 328 | 0 329 | 330 | 331 | 0 332 | 333 | 334 | 0 335 | 336 | 337 | 338 | 339 | 1 340 | 341 | 342 | 1 343 | 344 | 345 | 1 346 | 347 | 348 | 349 | 350 | 1 351 | 352 | 353 | 1 354 | 355 | 356 | 1 357 | 358 | 359 | 360 | 361 | 1 362 | 363 | 364 | 1 365 | 366 | 367 | 1 368 | 369 | 370 | 371 | 372 | 1 373 | 374 | 375 | 1 376 | 377 | 378 | 1 379 | 380 | 381 | 382 | 383 | 1 384 | 385 | 386 | 1 387 | 388 | 389 | 1 390 | 391 | 392 | 393 | 394 | 1 395 | 396 | 397 | 1 398 | 399 | 400 | 1 401 | 402 | 403 | 404 | 405 | 1 406 | 407 | 408 | 1 409 | 410 | 411 | 1 412 | 413 | 414 | 415 | 416 | 1 417 | 418 | 419 | 420 | 421 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 422 | 1 423 | 424 | 425 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 426 | 1 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 1 435 | 436 | 437 | 1 438 | 439 | 440 | 1 441 | 442 | 443 | 444 | 445 | 446 | 447 | Contents\Resources 448 | 1 449 | 450 | 451 | 452 | 453 | library\lib\armeabi-v7a 454 | 1 455 | 456 | 457 | 1 458 | 459 | 460 | 1 461 | 462 | 463 | 1 464 | 465 | 466 | 1 467 | 468 | 469 | 1 470 | 471 | 472 | 0 473 | 474 | 475 | 476 | 477 | 1 478 | 479 | 480 | 1 481 | 482 | 483 | 484 | 485 | Assets 486 | 1 487 | 488 | 489 | Assets 490 | 1 491 | 492 | 493 | 494 | 495 | Assets 496 | 1 497 | 498 | 499 | Assets 500 | 1 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | True 514 | 515 | 516 | 12 517 | 518 | 519 | 520 | 521 | 522 | -------------------------------------------------------------------------------- /Packages/10.2Tokyo/OpenSSL.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/Packages/10.2Tokyo/OpenSSL.res -------------------------------------------------------------------------------- /Packages/10.3Rio/OpenSSL.dpk: -------------------------------------------------------------------------------- 1 | package OpenSSL; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$DESCRIPTION 'Delphi OpenSSL Wrapper'} 29 | {$LIBSUFFIX '260'} 30 | {$IMPLICITBUILD OFF} 31 | 32 | requires 33 | rtl, 34 | IndySystem, 35 | IndyProtocols, 36 | IndyCore; 37 | 38 | contains 39 | OpenSSL.Core in '..\..\Source\OpenSSL.Core.pas', 40 | OpenSSL.EncUtils in '..\..\Source\OpenSSL.EncUtils.pas', 41 | OpenSSL.libeay32 in '..\..\Source\OpenSSL.libeay32.pas', 42 | OpenSSL.RandUtils in '..\..\Source\OpenSSL.RandUtils.pas', 43 | OpenSSL.RSAUtils in '..\..\Source\OpenSSL.RSAUtils.pas', 44 | OpenSSL.SMIMEUtils in '..\..\Source\OpenSSL.SMIMEUtils.pas'; 45 | 46 | end. 47 | -------------------------------------------------------------------------------- /Packages/10.3Rio/OpenSSL.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {4D944443-DB16-471B-BCD5-AE06947E67E3} 4 | OpenSSL.dpk 5 | 18.5 6 | None 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Package 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Cfg_1 29 | true 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | Delphi OpenSSL Wrapper 39 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 40 | 1040 41 | OpenSSL 42 | 260 43 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 44 | true 45 | true 46 | ../../Lib/$(DLLSUFFIX)/$(Platform)/$(Config) 47 | .\$(Platform)\$(Config) 48 | false 49 | false 50 | false 51 | false 52 | false 53 | true 54 | 55 | 56 | 1033 57 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 58 | true 59 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) 60 | 61 | 62 | DEBUG;$(DCC_Define) 63 | true 64 | false 65 | true 66 | true 67 | true 68 | 69 | 70 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) 71 | 1033 72 | true 73 | false 74 | 75 | 76 | false 77 | RELEASE;$(DCC_Define) 78 | 0 79 | 0 80 | 81 | 82 | 83 | MainSource 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Cfg_2 97 | Base 98 | 99 | 100 | Base 101 | 102 | 103 | Cfg_1 104 | Base 105 | 106 | 107 | 108 | Delphi.Personality.12 109 | Package 110 | 111 | 112 | 113 | OpenSSL.dpk 114 | 115 | 116 | DBExpress Enterprise Data Explorer Integration 117 | Microsoft Office 2000 Sample Automation Server Wrapper Components 118 | Microsoft Office XP Sample Automation Server Wrapper Components 119 | 120 | 121 | 122 | 123 | 124 | OpenSSL.bpl 125 | true 126 | 127 | 128 | 129 | 130 | OpenSSL.bpl 131 | true 132 | 133 | 134 | 135 | 136 | true 137 | 138 | 139 | 140 | 141 | true 142 | 143 | 144 | 145 | 146 | true 147 | 148 | 149 | 150 | 151 | true 152 | 153 | 154 | 155 | 156 | true 157 | 158 | 159 | 160 | 161 | true 162 | 163 | 164 | 165 | 166 | 1 167 | 168 | 169 | 0 170 | 171 | 172 | 173 | 174 | classes 175 | 1 176 | 177 | 178 | 179 | 180 | res\xml 181 | 1 182 | 183 | 184 | 185 | 186 | library\lib\armeabi-v7a 187 | 1 188 | 189 | 190 | 191 | 192 | library\lib\armeabi 193 | 1 194 | 195 | 196 | 197 | 198 | library\lib\mips 199 | 1 200 | 201 | 202 | 203 | 204 | 205 | library\lib\armeabi-v7a 206 | 1 207 | 208 | 209 | 210 | 211 | res\drawable 212 | 1 213 | 214 | 215 | 216 | 217 | res\values 218 | 1 219 | 220 | 221 | 222 | 223 | res\values-v21 224 | 1 225 | 226 | 227 | 228 | 229 | res\drawable 230 | 1 231 | 232 | 233 | 234 | 235 | res\drawable-xxhdpi 236 | 1 237 | 238 | 239 | 240 | 241 | res\drawable-ldpi 242 | 1 243 | 244 | 245 | 246 | 247 | res\drawable-mdpi 248 | 1 249 | 250 | 251 | 252 | 253 | res\drawable-hdpi 254 | 1 255 | 256 | 257 | 258 | 259 | res\drawable-xhdpi 260 | 1 261 | 262 | 263 | 264 | 265 | res\drawable-small 266 | 1 267 | 268 | 269 | 270 | 271 | res\drawable-normal 272 | 1 273 | 274 | 275 | 276 | 277 | res\drawable-large 278 | 1 279 | 280 | 281 | 282 | 283 | res\drawable-xlarge 284 | 1 285 | 286 | 287 | 288 | 289 | 1 290 | 291 | 292 | 1 293 | 294 | 295 | 0 296 | 297 | 298 | 299 | 300 | 1 301 | .framework 302 | 303 | 304 | 1 305 | .framework 306 | 307 | 308 | 0 309 | 310 | 311 | 312 | 313 | 1 314 | .dylib 315 | 316 | 317 | 1 318 | .dylib 319 | 320 | 321 | 0 322 | .dll;.bpl 323 | 324 | 325 | 326 | 327 | 1 328 | .dylib 329 | 330 | 331 | 1 332 | .dylib 333 | 334 | 335 | 1 336 | .dylib 337 | 338 | 339 | 1 340 | .dylib 341 | 342 | 343 | 1 344 | .dylib 345 | 346 | 347 | 0 348 | .bpl 349 | 350 | 351 | 352 | 353 | 0 354 | 355 | 356 | 0 357 | 358 | 359 | 0 360 | 361 | 362 | 0 363 | 364 | 365 | 0 366 | 367 | 368 | 0 369 | 370 | 371 | 0 372 | 373 | 374 | 375 | 376 | 1 377 | 378 | 379 | 1 380 | 381 | 382 | 1 383 | 384 | 385 | 386 | 387 | 1 388 | 389 | 390 | 1 391 | 392 | 393 | 1 394 | 395 | 396 | 397 | 398 | 1 399 | 400 | 401 | 1 402 | 403 | 404 | 1 405 | 406 | 407 | 408 | 409 | 1 410 | 411 | 412 | 1 413 | 414 | 415 | 1 416 | 417 | 418 | 419 | 420 | 1 421 | 422 | 423 | 1 424 | 425 | 426 | 1 427 | 428 | 429 | 430 | 431 | 1 432 | 433 | 434 | 1 435 | 436 | 437 | 1 438 | 439 | 440 | 441 | 442 | 1 443 | 444 | 445 | 1 446 | 447 | 448 | 1 449 | 450 | 451 | 452 | 453 | 1 454 | 455 | 456 | 457 | 458 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 459 | 1 460 | 461 | 462 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 463 | 1 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 1 472 | 473 | 474 | 1 475 | 476 | 477 | 1 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | Contents\Resources 486 | 1 487 | 488 | 489 | Contents\Resources 490 | 1 491 | 492 | 493 | 494 | 495 | library\lib\armeabi-v7a 496 | 1 497 | 498 | 499 | 1 500 | 501 | 502 | 1 503 | 504 | 505 | 1 506 | 507 | 508 | 1 509 | 510 | 511 | 1 512 | 513 | 514 | 1 515 | 516 | 517 | 0 518 | 519 | 520 | 521 | 522 | 1 523 | 524 | 525 | 1 526 | 527 | 528 | 529 | 530 | Assets 531 | 1 532 | 533 | 534 | Assets 535 | 1 536 | 537 | 538 | 539 | 540 | Assets 541 | 1 542 | 543 | 544 | Assets 545 | 1 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | True 560 | 561 | 562 | 12 563 | 564 | 565 | 566 | 567 | 568 | -------------------------------------------------------------------------------- /Packages/10.3Rio/OpenSSL.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/Packages/10.3Rio/OpenSSL.res -------------------------------------------------------------------------------- /Packages/XE7/OpenSSL.dpk: -------------------------------------------------------------------------------- 1 | package OpenSSL; 2 | 3 | {$R *.res} 4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} 5 | {$ALIGN 8} 6 | {$ASSERTIONS ON} 7 | {$BOOLEVAL OFF} 8 | {$DEBUGINFO OFF} 9 | {$EXTENDEDSYNTAX ON} 10 | {$IMPORTEDDATA ON} 11 | {$IOCHECKS ON} 12 | {$LOCALSYMBOLS ON} 13 | {$LONGSTRINGS ON} 14 | {$OPENSTRINGS ON} 15 | {$OPTIMIZATION OFF} 16 | {$OVERFLOWCHECKS OFF} 17 | {$RANGECHECKS OFF} 18 | {$REFERENCEINFO ON} 19 | {$SAFEDIVIDE OFF} 20 | {$STACKFRAMES ON} 21 | {$TYPEDADDRESS OFF} 22 | {$VARSTRINGCHECKS ON} 23 | {$WRITEABLECONST OFF} 24 | {$MINENUMSIZE 1} 25 | {$IMAGEBASE $400000} 26 | {$DEFINE DEBUG} 27 | {$ENDIF IMPLICITBUILDING} 28 | {$DESCRIPTION 'Delphi OpenSSL Wrapper'} 29 | {$LIBSUFFIX '210'} 30 | {$IMPLICITBUILD OFF} 31 | 32 | requires 33 | rtl, 34 | IndySystem, 35 | IndyProtocols, 36 | IndyCore; 37 | 38 | contains 39 | OpenSSL.Core in '..\..\Source\OpenSSL.Core.pas', 40 | OpenSSL.EncUtils in '..\..\Source\OpenSSL.EncUtils.pas', 41 | OpenSSL.libeay32 in '..\..\Source\OpenSSL.libeay32.pas', 42 | OpenSSL.RandUtils in '..\..\Source\OpenSSL.RandUtils.pas', 43 | OpenSSL.RSAUtils in '..\..\Source\OpenSSL.RSAUtils.pas', 44 | OpenSSL.SMIMEUtils in '..\..\Source\OpenSSL.SMIMEUtils.pas'; 45 | 46 | end. 47 | -------------------------------------------------------------------------------- /Packages/XE7/OpenSSL.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {4D944443-DB16-471B-BCD5-AE06947E67E3} 4 | OpenSSL.dpk 5 | 16.1 6 | None 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Package 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Cfg_1 29 | true 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Delphi OpenSSL Wrapper 40 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 41 | 1040 42 | OpenSSL 43 | 210 44 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 45 | true 46 | true 47 | ../../Lib/$(DLLSUFFIX)/$(Platform)/$(Config) 48 | .\$(Platform)\$(Config) 49 | false 50 | false 51 | false 52 | false 53 | false 54 | 55 | 56 | 1033 57 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 58 | true 59 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 60 | 61 | 62 | DEBUG;$(DCC_Define) 63 | true 64 | false 65 | true 66 | true 67 | true 68 | 69 | 70 | 1033 71 | true 72 | false 73 | 74 | 75 | false 76 | RELEASE;$(DCC_Define) 77 | 0 78 | 0 79 | 80 | 81 | 82 | MainSource 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | Cfg_2 96 | Base 97 | 98 | 99 | Base 100 | 101 | 102 | Cfg_1 103 | Base 104 | 105 | 106 | 107 | Delphi.Personality.12 108 | Package 109 | 110 | 111 | 112 | OpenSSL.dpk 113 | 114 | 115 | Microsoft Office 2000 Sample Automation Server Wrapper Components 116 | Microsoft Office XP Sample Automation Server Wrapper Components 117 | 118 | 119 | 120 | 121 | 122 | OpenSSL.bpl 123 | true 124 | 125 | 126 | 127 | 128 | true 129 | 130 | 131 | true 132 | 133 | 134 | 135 | 136 | OpenSSL.bpl 137 | true 138 | 139 | 140 | 141 | 142 | 1 143 | .dylib 144 | 145 | 146 | 0 147 | .bpl 148 | 149 | 150 | 1 151 | .dylib 152 | 153 | 154 | 1 155 | .dylib 156 | 157 | 158 | 159 | 160 | 1 161 | .dylib 162 | 163 | 164 | 0 165 | .dll;.bpl 166 | 167 | 168 | 169 | 170 | 1 171 | 172 | 173 | 1 174 | 175 | 176 | 177 | 178 | 179 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 180 | 1 181 | 182 | 183 | 184 | 185 | res\drawable-normal 186 | 1 187 | 188 | 189 | 190 | 191 | library\lib\x86 192 | 1 193 | 194 | 195 | 196 | 197 | 1 198 | 199 | 200 | 1 201 | 202 | 203 | 204 | 205 | 206 | library\lib\armeabi-v7a 207 | 1 208 | 209 | 210 | 211 | 212 | 1 213 | 214 | 215 | 1 216 | 217 | 218 | 219 | 220 | res\drawable-xlarge 221 | 1 222 | 223 | 224 | 225 | 226 | res\drawable-xhdpi 227 | 1 228 | 229 | 230 | 231 | 232 | 1 233 | 234 | 235 | 1 236 | 237 | 238 | 239 | 240 | res\drawable-xxhdpi 241 | 1 242 | 243 | 244 | 245 | 246 | library\lib\mips 247 | 1 248 | 249 | 250 | 251 | 252 | res\drawable 253 | 1 254 | 255 | 256 | 257 | 258 | 1 259 | 260 | 261 | 1 262 | 263 | 264 | 0 265 | 266 | 267 | 268 | 269 | 1 270 | .framework 271 | 272 | 273 | 0 274 | 275 | 276 | 277 | 278 | res\drawable-small 279 | 1 280 | 281 | 282 | 283 | 284 | 285 | 1 286 | 287 | 288 | Contents\MacOS 289 | 0 290 | 291 | 292 | 293 | 294 | classes 295 | 1 296 | 297 | 298 | 299 | 300 | 301 | 1 302 | 303 | 304 | 1 305 | 306 | 307 | 308 | 309 | res\drawable 310 | 1 311 | 312 | 313 | 314 | 315 | Contents\Resources 316 | 1 317 | 318 | 319 | 320 | 321 | 322 | 1 323 | 324 | 325 | 1 326 | 327 | 328 | 329 | 330 | 1 331 | 332 | 333 | library\lib\armeabi-v7a 334 | 1 335 | 336 | 337 | 0 338 | 339 | 340 | 1 341 | 342 | 343 | 1 344 | 345 | 346 | 347 | 348 | library\lib\armeabi 349 | 1 350 | 351 | 352 | 353 | 354 | res\drawable-large 355 | 1 356 | 357 | 358 | 359 | 360 | 0 361 | 362 | 363 | 0 364 | 365 | 366 | 0 367 | 368 | 369 | 0 370 | 371 | 372 | 0 373 | 374 | 375 | 376 | 377 | 1 378 | 379 | 380 | 1 381 | 382 | 383 | 384 | 385 | res\drawable-ldpi 386 | 1 387 | 388 | 389 | 390 | 391 | res\values 392 | 1 393 | 394 | 395 | 396 | 397 | 1 398 | 399 | 400 | 1 401 | 402 | 403 | 404 | 405 | res\drawable-mdpi 406 | 1 407 | 408 | 409 | 410 | 411 | res\drawable-hdpi 412 | 1 413 | 414 | 415 | 416 | 417 | 1 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | False 429 | True 430 | False 431 | 432 | 433 | 12 434 | 435 | 436 | 437 | 438 | 439 | -------------------------------------------------------------------------------- /Packages/XE7/OpenSSL.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/Packages/XE7/OpenSSL.res -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Delphi OpenSSL Library 2 | 3 | [Delphi](http://www.embarcadero.com/products/delphi) wrapper for [OpenSSL](https://openssl.org/). 4 | 5 | ## Features 6 | 7 | - Encrypt/Decrypt using RSA algorithm 8 | - Symmetric cipher routines 9 | - Base64 encoding e decoding 10 | - Basic PAM support 11 | - Generation of pseudo-random bit strings 12 | - Basic SMIME support 13 | - Generate RSA KeyPairs in PKCS PEM format 14 | 15 | ## Usage 16 | 17 | ### Encrypt with the public key inside X509 certificate 18 | 19 | *Command line:* 20 | 21 | OpenSSL rsautl -encrypt -certin -inkey publiccert.cer -in test.txt -out test.txt.cry 22 | 23 | 24 | *Source code:* 25 | 26 | ```delphi 27 | var 28 | RSAUtil :TRSAUtil; 29 | Cerificate :TX509Cerificate; 30 | begin 31 | RSAUtil := TRSAUtil.Create; 32 | try 33 | Cerificate := TX509Cerificate.Create; 34 | try 35 | Cerificate.LoadFromFile('publiccert.cer'); 36 | RSAUtil.PublicKey.LoadFromCertificate(Cerificate); 37 | RSAUtil.PublicEncrypt('test.txt', 'test.txt.cry'); 38 | finally 39 | Cerificate.Free; 40 | end; 41 | finally 42 | RSAUtil.Free; 43 | end; 44 | end; 45 | ``` 46 | 47 | ### Encrypt with the public key in PEM format 48 | 49 | *Command line:* 50 | 51 | OpenSSL rsautl -encrypt -pubin -inkey publickey.pem -in test.txt -out test.txt.cry 52 | 53 | *Source code:* 54 | 55 | ```delphi 56 | var 57 | RSAUtil :TRSAUtil; 58 | begin 59 | RSAUtil := TRSAUtil.Create; 60 | try 61 | RSAUtil.PublicKey.LoadFromFile('publickey.pem'); 62 | RSAUtil.PublicEncrypt('test.txt', 'test.txt.cry'); 63 | finally 64 | RSAUtil.Free; 65 | end; 66 | end; 67 | ``` 68 | 69 | ### Decrypt with the private key in PEM format 70 | 71 | *Command line:* 72 | 73 | OpenSSL rsautl -decrypt -inkey privatekey.pem -in test.txt.cry -out test.txt 74 | 75 | 76 | *Source code:* 77 | 78 | ```delphi 79 | var 80 | RSAUtil :TRSAUtil; 81 | begin 82 | RSAUtil := TRSAUtil.Create; 83 | try 84 | RSAUtil.PrivateKey.OnNeedPassphrase := PassphraseReader; 85 | RSAUtil.PrivateKey.LoadFromFile('privatekey.pem'); 86 | RSAUtil.PrivateDecrypt('test.txt.cry', 'test.txt'); 87 | finally 88 | RSAUtil.Free; 89 | end; 90 | end; 91 | ``` 92 | 93 | ### Encrypt with AES256 94 | 95 | *Command line:* 96 | 97 | OpenSSL enc -base64 -aes256 -in text.plain -out text.aes256 -k secure 98 | 99 | 100 | *Source code:* 101 | 102 | ```delphi 103 | var 104 | EncUtil :TEncUtil; 105 | begin 106 | EncUtil := TEncUtil.Create; 107 | try 108 | EncUtil.UseBase64 := True; 109 | EncUtil.Passphrase := 'secure'; 110 | EncUtil.Cipher := 'AES-256'; 111 | EncUtil.Encrypt('text.plain', 'text.aes256'); 112 | finally 113 | EncUtil.Free; 114 | end; 115 | end; 116 | ``` 117 | 118 | 119 | ## Todo 120 | 121 | - Symmetric cryptography (partially done) 122 | - compute hash functions 123 | - Sign e verify 124 | - RSA data management 125 | - Data managing for X509 126 | - Manage information according to the PKCS #12 standard 127 | 128 | ## Prerequisite 129 | 130 | OpenSSL library must be in your system path 131 | 132 | ## Installation 133 | 134 | - Add the source path "Source" to your Delphi project path 135 | - Run the demo and follow the tutorial 136 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.EncFrame.dfm: -------------------------------------------------------------------------------- 1 | object EncFrame: TEncFrame 2 | Left = 0 3 | Top = 0 4 | Width = 388 5 | Height = 287 6 | TabOrder = 0 7 | DesignSize = ( 8 | 388 9 | 287) 10 | object Label1: TLabel 11 | Left = 3 12 | Top = 131 13 | Width = 47 14 | Height = 13 15 | Caption = 'Input file:' 16 | end 17 | object Label2: TLabel 18 | Left = 3 19 | Top = 158 20 | Width = 55 21 | Height = 13 22 | Anchors = [akLeft, akTop, akRight] 23 | Caption = 'Output file:' 24 | end 25 | object Label3: TLabel 26 | Left = 3 27 | Top = 185 28 | Width = 31 29 | Height = 13 30 | Caption = 'Cipher' 31 | end 32 | object btnEncrypt: TButton 33 | Left = 3 34 | Top = 208 35 | Width = 142 36 | Height = 25 37 | Caption = 'Encrypt' 38 | TabOrder = 0 39 | OnClick = btnEncryptClick 40 | end 41 | object memTest: TMemo 42 | AlignWithMargins = True 43 | Left = 3 44 | Top = 3 45 | Width = 382 46 | Height = 89 47 | Align = alTop 48 | Lines.Strings = ( 49 | 'Hello, world!') 50 | TabOrder = 1 51 | end 52 | object btnDecrypt: TButton 53 | Left = 151 54 | Top = 208 55 | Width = 142 56 | Height = 25 57 | Caption = 'Decrypt' 58 | TabOrder = 2 59 | OnClick = btnDecryptClick 60 | end 61 | object edtInputFileName: TEdit 62 | Left = 64 63 | Top = 128 64 | Width = 321 65 | Height = 21 66 | Anchors = [akLeft, akTop, akRight] 67 | TabOrder = 3 68 | Text = 'edtInputFileName' 69 | end 70 | object edtOutputFileName: TEdit 71 | Left = 64 72 | Top = 155 73 | Width = 321 74 | Height = 21 75 | Anchors = [akLeft, akTop, akRight] 76 | TabOrder = 4 77 | Text = 'edtInputFileName' 78 | end 79 | object chkBase64: TCheckBox 80 | Left = 8 81 | Top = 246 82 | Width = 97 83 | Height = 17 84 | Caption = 'Use base64' 85 | Checked = True 86 | State = cbChecked 87 | TabOrder = 5 88 | end 89 | object BtnGenrateFile: TButton 90 | AlignWithMargins = True 91 | Left = 3 92 | Top = 98 93 | Width = 382 94 | Height = 25 95 | Align = alTop 96 | Caption = 'Create test file from memo' 97 | TabOrder = 6 98 | OnClick = BtnGenrateFileClick 99 | end 100 | object cmbCipher: TComboBox 101 | Left = 64 102 | Top = 182 103 | Width = 321 104 | Height = 21 105 | TabOrder = 7 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.EncFrame.pas: -------------------------------------------------------------------------------- 1 | unit SSLDemo.EncFrame; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 7 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 8 | 9 | type 10 | TEncFrame = class(TFrame) 11 | btnEncrypt: TButton; 12 | memTest: TMemo; 13 | btnDecrypt: TButton; 14 | Label1: TLabel; 15 | Label2: TLabel; 16 | edtInputFileName: TEdit; 17 | edtOutputFileName: TEdit; 18 | chkBase64: TCheckBox; 19 | BtnGenrateFile: TButton; 20 | cmbCipher: TComboBox; 21 | Label3: TLabel; 22 | procedure btnEncryptClick(Sender: TObject); 23 | procedure btnDecryptClick(Sender: TObject); 24 | procedure BtnGenrateFileClick(Sender: TObject); 25 | private 26 | { Private declarations } 27 | public 28 | constructor Create(AOwner: TComponent); override; 29 | end; 30 | 31 | implementation 32 | 33 | {$R *.dfm} 34 | 35 | uses 36 | OpenSSL.EncUtils; 37 | 38 | procedure TEncFrame.btnEncryptClick(Sender: TObject); 39 | var 40 | EncUtil :TEncUtil; 41 | begin 42 | EncUtil := TEncUtil.Create; 43 | try 44 | EncUtil.UseBase64 := chkBase64.Checked; 45 | EncUtil.Passphrase := InputBox(Name, 'password', ''); 46 | EncUtil.Cipher := cmbCipher.Text; 47 | EncUtil.Encrypt(edtInputFileName.Text, edtOutputFileName.Text); 48 | finally 49 | EncUtil.Free; 50 | end; 51 | end; 52 | 53 | procedure TEncFrame.BtnGenrateFileClick(Sender: TObject); 54 | begin 55 | memTest.Lines.SaveToFile(edtInputFileName.Text); 56 | end; 57 | 58 | constructor TEncFrame.Create(AOwner: TComponent); 59 | var 60 | TestFolder :string; 61 | begin 62 | inherited; 63 | TestFolder := StringReplace(ExtractFilePath(ParamStr(0)), 'Samples\SSLDemo', 'TestData', [rfReplaceAll, rfIgnoreCase]); 64 | 65 | edtInputFileName.Text := TestFolder + 'AES_TEST_CLEAR.txt'; 66 | edtOutputFileName.Text := TestFolder + 'AES_TEST_ENC.txt'; 67 | TEncUtil.SupportedCiphers(cmbCipher.Items); 68 | end; 69 | 70 | procedure TEncFrame.btnDecryptClick(Sender: TObject); 71 | var 72 | EncUtil :TEncUtil; 73 | begin 74 | EncUtil := TEncUtil.Create; 75 | try 76 | EncUtil.UseBase64 := chkBase64.Checked; 77 | EncUtil.Passphrase := InputBox(Name, 'password', ''); 78 | EncUtil.Cipher := cmbCipher.Text; 79 | EncUtil.Decrypt(edtOutputFileName.Text, edtInputFileName.Text); 80 | finally 81 | EncUtil.Free; 82 | end; 83 | end; 84 | 85 | end. 86 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.KeyPairFrame.dfm: -------------------------------------------------------------------------------- 1 | object KeyPairFrame: TKeyPairFrame 2 | Left = 0 3 | Top = 0 4 | Width = 468 5 | Height = 396 6 | TabOrder = 0 7 | object btnKeyPairGen: TButton 8 | Left = 144 9 | Top = 112 10 | Width = 169 11 | Height = 25 12 | Caption = 'Generate key pair' 13 | TabOrder = 0 14 | OnClick = btnKeyPairGenClick 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.KeyPairFrame.pas: -------------------------------------------------------------------------------- 1 | unit SSLDemo.KeyPairFrame; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 7 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, OpenSSL.RSAUtils, 8 | Vcl.StdCtrls; 9 | 10 | type 11 | TKeyPairFrame = class(TFrame) 12 | btnKeyPairGen: TButton; 13 | procedure btnKeyPairGenClick(Sender: TObject); 14 | private 15 | { Private declarations } 16 | public 17 | { Public declarations } 18 | end; 19 | 20 | implementation 21 | 22 | {$R *.dfm} 23 | 24 | procedure TKeyPairFrame.btnKeyPairGenClick(Sender: TObject); 25 | var 26 | KeyPair: TRSAKeyPair; 27 | RSAUtil :TRSAUtil; 28 | begin 29 | KeyPair := TRSAKeyPair.Create; 30 | try 31 | KeyPair.GenerateKey; 32 | 33 | RSAUtil := TRSAUtil.Create; 34 | try 35 | RSAUtil.PrivateKey := KeyPair.PrivateKey; 36 | finally 37 | RSAUtil.Free; 38 | end; 39 | 40 | finally 41 | KeyPair.Free; 42 | end; 43 | end; 44 | 45 | end. 46 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.MainForm.dfm: -------------------------------------------------------------------------------- 1 | object MainForm: TMainForm 2 | Left = 0 3 | Top = 0 4 | Caption = 'SSLDemo' 5 | ClientHeight = 544 6 | ClientWidth = 613 7 | Color = clBtnFace 8 | Font.Charset = DEFAULT_CHARSET 9 | Font.Color = clWindowText 10 | Font.Height = -11 11 | Font.Name = 'Tahoma' 12 | Font.Style = [] 13 | OldCreateOrder = False 14 | OnCreate = FormCreate 15 | PixelsPerInch = 96 16 | TextHeight = 13 17 | object pgcMain: TPageControl 18 | Left = 0 19 | Top = 0 20 | Width = 613 21 | Height = 544 22 | Align = alClient 23 | TabOrder = 0 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.MainForm.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit SSLDemo.MainForm; 23 | 24 | interface 25 | 26 | uses 27 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 28 | System.Classes, Vcl.StdCtrls, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, 29 | Vcl.ComCtrls; 30 | 31 | type 32 | TMainForm = class(TForm) 33 | pgcMain: TPageControl; 34 | procedure FormCreate(Sender: TObject); 35 | private 36 | procedure AddFrame(const Caption: string; FrameClass: TControlClass); 37 | public 38 | { Public declarations } 39 | end; 40 | 41 | var 42 | MainForm: TMainForm; 43 | 44 | implementation 45 | 46 | {$R *.dfm} 47 | 48 | uses 49 | SSLDemo.MainFrame, SSLDemo.RSABufferFrame, SSLDemo.EncFrame, SSLDemo.UnpackPKCS7Frame, 50 | SSLDemo.RandFrame, SSLDemo.KeyPairFrame; 51 | 52 | { TMainForm } 53 | 54 | procedure TMainForm.AddFrame(const Caption: string; 55 | FrameClass: TControlClass); 56 | var 57 | TabSheet: TTabSheet; 58 | AFrame: TControl; 59 | begin 60 | TabSheet := TTabSheet.Create(pgcMain); 61 | TabSheet.Caption := Caption; 62 | TabSheet.PageControl := pgcMain; 63 | 64 | AFrame := FrameClass.Create(Application); 65 | AFrame.Parent := TabSheet; 66 | end; 67 | 68 | procedure TMainForm.FormCreate(Sender: TObject); 69 | begin 70 | AddFrame('Tutorial', TMainFrame); 71 | AddFrame('RSABuffer', TRSABufferFrame); 72 | AddFrame('Encryption', TEncFrame); 73 | AddFrame('Random', TRandomFrame); 74 | AddFrame('Unpack PKCS7', TUnpackPKCS7Frame); 75 | AddFrame('KeyPair', TKeyPairFrame); 76 | end; 77 | 78 | end. 79 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.MainFrame.dfm: -------------------------------------------------------------------------------- 1 | object MainFrame: TMainFrame 2 | Left = 0 3 | Top = 0 4 | Width = 591 5 | Height = 559 6 | Font.Charset = DEFAULT_CHARSET 7 | Font.Color = clWindowText 8 | Font.Height = -11 9 | Font.Name = 'Tahoma' 10 | Font.Style = [] 11 | ParentFont = False 12 | TabOrder = 0 13 | object lblTextToCrypt: TLabel 14 | Left = 24 15 | Top = 275 16 | Width = 38 17 | Height = 13 18 | Caption = 'Test file' 19 | end 20 | object lblCertPath: TLabel 21 | Left = 24 22 | Top = 147 23 | Width = 50 24 | Height = 13 25 | Caption = 'Certificate' 26 | end 27 | object lblPriv: TLabel 28 | Left = 24 29 | Top = 174 30 | Width = 54 31 | Height = 13 32 | Caption = 'Private key' 33 | end 34 | object Label1: TLabel 35 | Left = 24 36 | Top = 201 37 | Width = 47 38 | Height = 13 39 | Caption = 'Public key' 40 | end 41 | object Label2: TLabel 42 | Left = 24 43 | Top = 16 44 | Width = 277 45 | Height = 13 46 | Caption = '1. Install OPENSSL and add it to your system path' 47 | Font.Charset = DEFAULT_CHARSET 48 | Font.Color = clWindowText 49 | Font.Height = -11 50 | Font.Name = 'Tahoma' 51 | Font.Style = [fsBold] 52 | ParentFont = False 53 | end 54 | object Label3: TLabel 55 | Left = 60 56 | Top = 35 57 | Width = 215 58 | Height = 13 59 | Caption = '2. Choose one of the following options:' 60 | Font.Charset = DEFAULT_CHARSET 61 | Font.Color = clWindowText 62 | Font.Height = -11 63 | Font.Name = 'Tahoma' 64 | Font.Style = [fsBold] 65 | ParentFont = False 66 | end 67 | object Label4: TLabel 68 | Left = 24 69 | Top = 118 70 | Width = 217 71 | Height = 13 72 | Caption = '4. Check the following files are created' 73 | Font.Charset = DEFAULT_CHARSET 74 | Font.Color = clWindowText 75 | Font.Height = -11 76 | Font.Name = 'Tahoma' 77 | Font.Style = [fsBold] 78 | ParentFont = False 79 | end 80 | object Label5: TLabel 81 | Left = 24 82 | Top = 248 83 | Width = 122 84 | Height = 13 85 | Caption = '5. Generate a test file' 86 | Font.Charset = DEFAULT_CHARSET 87 | Font.Color = clWindowText 88 | Font.Height = -11 89 | Font.Name = 'Tahoma' 90 | Font.Style = [fsBold] 91 | ParentFont = False 92 | end 93 | object Label6: TLabel 94 | Left = 24 95 | Top = 304 96 | Width = 199 97 | Height = 13 98 | Caption = '6. Try to encrypt with the cerificate' 99 | Font.Charset = DEFAULT_CHARSET 100 | Font.Color = clWindowText 101 | Font.Height = -11 102 | Font.Name = 'Tahoma' 103 | Font.Style = [fsBold] 104 | ParentFont = False 105 | end 106 | object Label7: TLabel 107 | Left = 24 108 | Top = 354 109 | Width = 211 110 | Height = 13 111 | Caption = '7. Try to decrypt with the private key' 112 | Font.Charset = DEFAULT_CHARSET 113 | Font.Color = clWindowText 114 | Font.Height = -11 115 | Font.Name = 'Tahoma' 116 | Font.Style = [fsBold] 117 | ParentFont = False 118 | end 119 | object Label8: TLabel 120 | Left = 24 121 | Top = 404 122 | Width = 203 123 | Height = 13 124 | Caption = '8. Try to encrypt with the public key' 125 | Font.Charset = DEFAULT_CHARSET 126 | Font.Color = clWindowText 127 | Font.Height = -11 128 | Font.Name = 'Tahoma' 129 | Font.Style = [fsBold] 130 | ParentFont = False 131 | end 132 | object Label9: TLabel 133 | Left = 24 134 | Top = 99 135 | Width = 129 136 | Height = 13 137 | Caption = '3. Run create_p7m.bat' 138 | Font.Charset = DEFAULT_CHARSET 139 | Font.Color = clWindowText 140 | Font.Height = -11 141 | Font.Name = 'Tahoma' 142 | Font.Style = [fsBold] 143 | ParentFont = False 144 | end 145 | object Label10: TLabel 146 | Left = 24 147 | Top = 228 148 | Width = 59 149 | Height = 13 150 | Caption = 'P7M test file' 151 | end 152 | object Label11: TLabel 153 | Left = 22 154 | Top = 460 155 | Width = 114 156 | Height = 13 157 | Caption = '9. Genrate Key Pairs' 158 | Font.Charset = DEFAULT_CHARSET 159 | Font.Color = clWindowText 160 | Font.Height = -11 161 | Font.Name = 'Tahoma' 162 | Font.Style = [fsBold] 163 | ParentFont = False 164 | end 165 | object Label12: TLabel 166 | Left = 72 167 | Top = 54 168 | Width = 298 169 | Height = 13 170 | Caption = '2a. Go to the testdata folder and run create_cert.bat' 171 | Font.Charset = DEFAULT_CHARSET 172 | Font.Color = clWindowText 173 | Font.Height = -11 174 | Font.Name = 'Tahoma' 175 | Font.Style = [fsBold] 176 | ParentFont = False 177 | end 178 | object Label13: TLabel 179 | Left = 72 180 | Top = 73 181 | Width = 417 182 | Height = 13 183 | Caption = 184 | '2b. Press the "Generate KeyPairs" button (it doen'#39't create the c' + 185 | 'ertificate)' 186 | Font.Charset = DEFAULT_CHARSET 187 | Font.Color = clWindowText 188 | Font.Height = -11 189 | Font.Name = 'Tahoma' 190 | Font.Style = [fsBold] 191 | ParentFont = False 192 | end 193 | object edtTextToCrypt: TEdit 194 | Left = 136 195 | Top = 272 196 | Width = 353 197 | Height = 21 198 | TabOrder = 4 199 | end 200 | object edtCertFile: TEdit 201 | Left = 136 202 | Top = 144 203 | Width = 435 204 | Height = 21 205 | TabOrder = 0 206 | end 207 | object btnCryptWithKey: TButton 208 | Left = 24 209 | Top = 424 210 | Width = 131 211 | Height = 25 212 | Caption = 'Public Crypt' 213 | TabOrder = 8 214 | OnClick = btnCryptWithKeyClick 215 | end 216 | object edtPriv: TEdit 217 | Left = 136 218 | Top = 171 219 | Width = 435 220 | Height = 21 221 | TabOrder = 1 222 | end 223 | object btnDecryptWithKey: TButton 224 | Left = 24 225 | Top = 373 226 | Width = 131 227 | Height = 25 228 | Caption = 'Private decrypt' 229 | TabOrder = 7 230 | OnClick = btnDecryptWithKeyClick 231 | end 232 | object edtPub: TEdit 233 | Left = 136 234 | Top = 198 235 | Width = 435 236 | Height = 21 237 | TabOrder = 2 238 | end 239 | object btnCryptWithCert: TButton 240 | Left = 24 241 | Top = 323 242 | Width = 131 243 | Height = 25 244 | Caption = 'Public Crypt with cert' 245 | TabOrder = 6 246 | OnClick = btnCryptWithCertClick 247 | end 248 | object btnGenerateSampleFile: TButton 249 | Left = 495 250 | Top = 270 251 | Width = 75 252 | Height = 25 253 | Caption = 'Generate' 254 | TabOrder = 5 255 | OnClick = btnGenerateSampleFileClick 256 | end 257 | object edtP7MTestFile: TEdit 258 | Left = 136 259 | Top = 225 260 | Width = 435 261 | Height = 21 262 | TabOrder = 3 263 | end 264 | object BtnGenerateKeyPairs: TButton 265 | Left = 22 266 | Top = 479 267 | Width = 131 268 | Height = 25 269 | Caption = 'Generate KeyPairs' 270 | TabOrder = 9 271 | OnClick = BtnGenerateKeyPairsClick 272 | end 273 | end 274 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.MainFrame.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit SSLDemo.MainFrame; 23 | 24 | interface 25 | 26 | uses 27 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 28 | System.Classes, Vcl.StdCtrls, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; 29 | 30 | type 31 | TMainFrame = class(TFrame) 32 | edtTextToCrypt: TEdit; 33 | lblTextToCrypt: TLabel; 34 | lblCertPath: TLabel; 35 | edtCertFile: TEdit; 36 | btnCryptWithKey: TButton; 37 | lblPriv: TLabel; 38 | edtPriv: TEdit; 39 | btnDecryptWithKey: TButton; 40 | Label1: TLabel; 41 | edtPub: TEdit; 42 | btnCryptWithCert: TButton; 43 | Label2: TLabel; 44 | Label3: TLabel; 45 | Label4: TLabel; 46 | Label5: TLabel; 47 | btnGenerateSampleFile: TButton; 48 | Label6: TLabel; 49 | Label7: TLabel; 50 | Label8: TLabel; 51 | Label9: TLabel; 52 | Label10: TLabel; 53 | edtP7MTestFile: TEdit; 54 | Label11: TLabel; 55 | BtnGenerateKeyPairs: TButton; 56 | Label12: TLabel; 57 | Label13: TLabel; 58 | procedure btnCryptWithKeyClick(Sender: TObject); 59 | procedure btnDecryptWithKeyClick(Sender: TObject); 60 | procedure btnCryptWithCertClick(Sender: TObject); 61 | procedure btnGenerateSampleFileClick(Sender: TObject); 62 | procedure BtnGenerateKeyPairsClick(Sender: TObject); 63 | private 64 | procedure PassphraseReader(Sender :TObject; var Passphrase :string); 65 | public 66 | constructor Create(AOwner: TComponent); override; 67 | end; 68 | 69 | implementation 70 | 71 | {$R *.dfm} 72 | 73 | uses 74 | OpenSSL.RSAUtils, System.IOUtils; 75 | 76 | { TMainForm } 77 | 78 | procedure TMainFrame.btnCryptWithKeyClick(Sender: TObject); 79 | var 80 | RSAUtil :TRSAUtil; 81 | begin 82 | RSAUtil := TRSAUtil.Create; 83 | try 84 | RSAUtil.PublicKey.LoadFromFile(edtPub.Text); 85 | RSAUtil.PublicEncrypt(edtTextToCrypt.Text, edtTextToCrypt.Text + '.keycry'); 86 | finally 87 | RSAUtil.Free; 88 | end; 89 | end; 90 | 91 | procedure TMainFrame.btnDecryptWithKeyClick(Sender: TObject); 92 | var 93 | RSAUtil :TRSAUtil; 94 | begin 95 | RSAUtil := TRSAUtil.Create; 96 | try 97 | RSAUtil.PrivateKey.OnNeedPassphrase := PassphraseReader; 98 | RSAUtil.PrivateKey.LoadFromFile(edtPriv.Text); 99 | RSAUtil.PrivateDecrypt(edtTextToCrypt.Text + '.keycry', edtTextToCrypt.Text + '.certdecry.txt'); 100 | finally 101 | RSAUtil.Free; 102 | end; 103 | end; 104 | 105 | procedure TMainFrame.btnCryptWithCertClick(Sender: TObject); 106 | var 107 | RSAUtil :TRSAUtil; 108 | Cerificate :TX509Cerificate; 109 | begin 110 | RSAUtil := TRSAUtil.Create; 111 | try 112 | Cerificate := TX509Cerificate.Create; 113 | try 114 | Cerificate.LoadFromFile(edtCertFile.Text); 115 | RSAUtil.PublicKey.LoadFromCertificate(Cerificate); 116 | RSAUtil.PublicEncrypt(edtTextToCrypt.Text, edtTextToCrypt.Text + '.certcry'); 117 | finally 118 | Cerificate.Free; 119 | end; 120 | finally 121 | RSAUtil.Free; 122 | end; 123 | end; 124 | 125 | procedure TMainFrame.btnGenerateSampleFileClick(Sender: TObject); 126 | var 127 | SL :TStringList; 128 | begin 129 | SL := TStringList.Create; 130 | try 131 | SL.Text := 'Hello, world!'; 132 | SL.SaveToFile(edtTextToCrypt.Text, TEncoding.Unicode); 133 | finally 134 | SL.Free; 135 | end; 136 | end; 137 | 138 | constructor TMainFrame.Create(AOwner: TComponent); 139 | var 140 | TestFolder :string; 141 | begin 142 | inherited; 143 | TestFolder := StringReplace(ExtractFilePath(ParamStr(0)), 'Samples' + PathDelim + 'SSLDemo', 'TestData', [rfReplaceAll, rfIgnoreCase]); 144 | 145 | edtCertFile.Text := TestFolder + 'publiccert.pem'; 146 | edtPriv.Text := TestFolder + 'privatekey.pem'; 147 | edtPub.Text := TestFolder + 'publickey.pem'; 148 | edtTextToCrypt.Text := TestFolder + 'test.txt'; 149 | edtP7MTestFile.Text := TestFolder + 'TestPKCS7.pdf.p7m'; 150 | end; 151 | 152 | procedure TMainFrame.PassphraseReader(Sender: TObject; var Passphrase: string); 153 | begin 154 | Passphrase := InputBox(Name, 'Passphrase', ''); 155 | end; 156 | 157 | procedure TMainFrame.BtnGenerateKeyPairsClick(Sender: TObject); 158 | var 159 | KeyPair: TRSAKeyPair; 160 | begin 161 | KeyPair := TRSAKeyPair.Create; 162 | try 163 | KeyPair.GenerateKey; 164 | KeyPair.PrivateKey.SaveToFile(edtPriv.Text); 165 | KeyPair.PublicKey.SaveToFile(edtPub.Text); 166 | finally 167 | KeyPair.Free; 168 | end; 169 | end; 170 | 171 | end. 172 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.RSABufferFrame.dfm: -------------------------------------------------------------------------------- 1 | object RSABufferFrame: TRSABufferFrame 2 | Left = 0 3 | Top = 0 4 | Width = 451 5 | Height = 621 6 | Align = alClient 7 | AutoScroll = True 8 | TabOrder = 0 9 | ExplicitHeight = 305 10 | object grpPublicKey: TGroupBox 11 | AlignWithMargins = True 12 | Left = 3 13 | Top = 3 14 | Width = 428 15 | Height = 254 16 | Align = alTop 17 | Caption = 'Public key' 18 | TabOrder = 0 19 | object btnLoadPubKeyIntoMem: TButton 20 | Left = 16 21 | Top = 13 22 | Width = 385 23 | Height = 25 24 | Caption = 'Load public key into memo' 25 | TabOrder = 0 26 | OnClick = btnLoadPubKeyIntoMemClick 27 | end 28 | object btnLoadPublicKey: TButton 29 | Left = 16 30 | Top = 215 31 | Width = 257 32 | Height = 25 33 | Caption = 'Load memo into TRSAPublicKey' 34 | TabOrder = 1 35 | OnClick = btnLoadPublicKeyClick 36 | end 37 | object edtPub: TEdit 38 | Left = 16 39 | Top = 44 40 | Width = 385 41 | Height = 21 42 | TabOrder = 2 43 | end 44 | object memPub: TMemo 45 | Left = 16 46 | Top = 71 47 | Width = 385 48 | Height = 138 49 | Font.Charset = DEFAULT_CHARSET 50 | Font.Color = clWindowText 51 | Font.Height = -12 52 | Font.Name = 'Courier New' 53 | Font.Style = [] 54 | Lines.Strings = ( 55 | 'memPub') 56 | ParentFont = False 57 | ScrollBars = ssBoth 58 | TabOrder = 3 59 | WordWrap = False 60 | end 61 | object cmbPublicKeyFormat: TComboBox 62 | Left = 279 63 | Top = 217 64 | Width = 122 65 | Height = 21 66 | Style = csDropDownList 67 | ItemIndex = 0 68 | TabOrder = 4 69 | Text = 'Default' 70 | Items.Strings = ( 71 | 'Default' 72 | 'RSAPublicKey') 73 | end 74 | end 75 | object grpPrivateKey: TGroupBox 76 | AlignWithMargins = True 77 | Left = 3 78 | Top = 263 79 | Width = 428 80 | Height = 254 81 | Align = alTop 82 | Caption = 'Private key' 83 | TabOrder = 1 84 | object btnLoadPrivKeyIntoMemo: TButton 85 | Left = 16 86 | Top = 13 87 | Width = 385 88 | Height = 25 89 | Caption = 'Load private key into memo' 90 | TabOrder = 0 91 | OnClick = btnLoadPrivKeyIntoMemoClick 92 | end 93 | object btnLoadPrivateKey: TButton 94 | Left = 16 95 | Top = 215 96 | Width = 257 97 | Height = 25 98 | Caption = 'Load memo into TRSAPrivateKey' 99 | TabOrder = 1 100 | OnClick = btnLoadPrivateKeyClick 101 | end 102 | object edtPriv: TEdit 103 | Left = 16 104 | Top = 44 105 | Width = 385 106 | Height = 21 107 | TabOrder = 2 108 | end 109 | object memPriv: TMemo 110 | Left = 16 111 | Top = 71 112 | Width = 385 113 | Height = 138 114 | Font.Charset = DEFAULT_CHARSET 115 | Font.Color = clWindowText 116 | Font.Height = -12 117 | Font.Name = 'Courier New' 118 | Font.Style = [] 119 | Lines.Strings = ( 120 | 'memPriv') 121 | ParentFont = False 122 | ScrollBars = ssBoth 123 | TabOrder = 3 124 | WordWrap = False 125 | end 126 | object cmbPrivateKeyFormat: TComboBox 127 | Left = 279 128 | Top = 217 129 | Width = 122 130 | Height = 21 131 | Style = csDropDownList 132 | ItemIndex = 0 133 | TabOrder = 4 134 | Text = 'Default' 135 | Items.Strings = ( 136 | 'Default' 137 | 'RSAPrivateKey') 138 | end 139 | end 140 | object grpCertificate: TGroupBox 141 | AlignWithMargins = True 142 | Left = 3 143 | Top = 523 144 | Width = 428 145 | Height = 254 146 | Align = alTop 147 | Caption = 'Certificate' 148 | TabOrder = 2 149 | object btnLoadCertIntoMemo: TButton 150 | Left = 16 151 | Top = 16 152 | Width = 385 153 | Height = 25 154 | Caption = 'Load certificate into memo' 155 | TabOrder = 0 156 | OnClick = btnLoadCertIntoMemoClick 157 | end 158 | object btnLoadCert: TButton 159 | Left = 16 160 | Top = 215 161 | Width = 385 162 | Height = 25 163 | Caption = 'Load memo into TX509Cerificate' 164 | TabOrder = 1 165 | OnClick = btnLoadCertClick 166 | end 167 | object edtCert: TEdit 168 | Left = 16 169 | Top = 44 170 | Width = 385 171 | Height = 21 172 | TabOrder = 2 173 | end 174 | object memCert: TMemo 175 | Left = 16 176 | Top = 71 177 | Width = 385 178 | Height = 138 179 | Font.Charset = DEFAULT_CHARSET 180 | Font.Color = clWindowText 181 | Font.Height = -12 182 | Font.Name = 'Courier New' 183 | Font.Style = [] 184 | Lines.Strings = ( 185 | 'memCert') 186 | ParentFont = False 187 | ScrollBars = ssBoth 188 | TabOrder = 3 189 | WordWrap = False 190 | end 191 | end 192 | end 193 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.RSABufferFrame.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit SSLDemo.RSABufferFrame; 23 | 24 | interface 25 | 26 | uses 27 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 28 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 29 | 30 | type 31 | TRSABufferFrame = class(TFrame) 32 | memPub: TMemo; 33 | btnLoadPubKeyIntoMem: TButton; 34 | edtPub: TEdit; 35 | btnLoadPublicKey: TButton; 36 | grpPublicKey: TGroupBox; 37 | grpPrivateKey: TGroupBox; 38 | btnLoadPrivKeyIntoMemo: TButton; 39 | btnLoadPrivateKey: TButton; 40 | edtPriv: TEdit; 41 | memPriv: TMemo; 42 | grpCertificate: TGroupBox; 43 | btnLoadCertIntoMemo: TButton; 44 | btnLoadCert: TButton; 45 | edtCert: TEdit; 46 | memCert: TMemo; 47 | cmbPrivateKeyFormat: TComboBox; 48 | cmbPublicKeyFormat: TComboBox; 49 | procedure btnLoadPubKeyIntoMemClick(Sender: TObject); 50 | procedure btnLoadPrivateKeyClick(Sender: TObject); 51 | procedure btnLoadPrivKeyIntoMemoClick(Sender: TObject); 52 | procedure btnLoadCertIntoMemoClick(Sender: TObject); 53 | procedure btnLoadCertClick(Sender: TObject); 54 | procedure btnLoadPublicKeyClick(Sender: TObject); 55 | private 56 | procedure PassphraseReader(Sender: TObject; var Passphrase: string); 57 | { Private declarations } 58 | public 59 | constructor Create(AOwner: TComponent); override; 60 | end; 61 | 62 | implementation 63 | 64 | uses 65 | OpenSSL.RSAUtils; 66 | 67 | {$R *.dfm} 68 | 69 | { TRSABufferFrame } 70 | 71 | procedure TRSABufferFrame.btnLoadCertClick(Sender: TObject); 72 | var 73 | Buffer :TStream; 74 | Cerificate :TX509Cerificate; 75 | begin 76 | Buffer := TStringStream.Create(memCert.Text); 77 | try 78 | Cerificate := TX509Cerificate.Create; 79 | try 80 | Cerificate.LoadFromStream(Buffer); 81 | ShowMessage(Cerificate.Print); 82 | finally 83 | Cerificate.Free; 84 | end; 85 | finally 86 | Buffer.Free; 87 | end; 88 | end; 89 | 90 | procedure TRSABufferFrame.btnLoadCertIntoMemoClick(Sender: TObject); 91 | begin 92 | memCert.Lines.LoadFromFile(edtCert.Text); 93 | end; 94 | 95 | procedure TRSABufferFrame.btnLoadPrivKeyIntoMemoClick(Sender: TObject); 96 | begin 97 | memPriv.Lines.LoadFromFile(edtPriv.Text); 98 | end; 99 | 100 | procedure TRSABufferFrame.btnLoadPubKeyIntoMemClick(Sender: TObject); 101 | begin 102 | memPub.Lines.LoadFromFile(edtPub.Text); 103 | end; 104 | 105 | procedure TRSABufferFrame.btnLoadPublicKeyClick(Sender: TObject); 106 | var 107 | Buffer :TStream; 108 | PublicKey :TRSAPublicKey; 109 | begin 110 | Buffer := TStringStream.Create(memPub.Text); 111 | try 112 | PublicKey := TRSAPublicKey.Create; 113 | try 114 | PublicKey.LoadFromStream(Buffer, TPublicKeyFormat(cmbPublicKeyFormat.ItemIndex)); 115 | ShowMessage(PublicKey.Print); 116 | finally 117 | PublicKey.Free; 118 | end; 119 | finally 120 | Buffer.Free; 121 | end; 122 | end; 123 | 124 | procedure TRSABufferFrame.btnLoadPrivateKeyClick(Sender: TObject); 125 | var 126 | Buffer :TStream; 127 | PrivateKey :TRSAPrivateKey; 128 | begin 129 | Buffer := TStringStream.Create(memPriv.Text); 130 | try 131 | PrivateKey := TRSAPrivateKey.Create; 132 | try 133 | PrivateKey.OnNeedPassphrase := PassphraseReader; 134 | PrivateKey.LoadFromStream(Buffer, TPrivateKeyFormat(cmbPrivateKeyFormat.ItemIndex)); 135 | ShowMessage(PrivateKey.Print); 136 | finally 137 | PrivateKey.Free; 138 | end; 139 | finally 140 | Buffer.Free; 141 | end; 142 | end; 143 | 144 | constructor TRSABufferFrame.Create(AOwner: TComponent); 145 | var 146 | TestFolder :string; 147 | begin 148 | inherited; 149 | TestFolder := StringReplace(ExtractFilePath(ParamStr(0)), 'Samples\SSLDemo', 'TestData', [rfReplaceAll, rfIgnoreCase]); 150 | 151 | edtCert.Text := TestFolder + 'publiccert.pem'; 152 | edtPriv.Text := TestFolder + 'privatekey.pem'; 153 | edtPub.Text := TestFolder + 'publickey.pem'; 154 | end; 155 | 156 | procedure TRSABufferFrame.PassphraseReader(Sender: TObject; var Passphrase: string); 157 | begin 158 | Passphrase := InputBox(Name, 'Passphrase', ''); 159 | end; 160 | 161 | end. 162 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.RandFrame.dfm: -------------------------------------------------------------------------------- 1 | object RandomFrame: TRandomFrame 2 | Left = 0 3 | Top = 0 4 | Width = 320 5 | Height = 240 6 | TabOrder = 0 7 | object LabelSize: TLabel 8 | Left = 23 9 | Top = 27 10 | Width = 144 11 | Height = 13 12 | Caption = 'Random number len (in bytes)' 13 | end 14 | object EditSize: TEdit 15 | Left = 173 16 | Top = 24 17 | Width = 44 18 | Height = 21 19 | NumbersOnly = True 20 | TabOrder = 0 21 | Text = '20' 22 | end 23 | object EditResult: TEdit 24 | Left = 23 25 | Top = 88 26 | Width = 194 27 | Height = 21 28 | ReadOnly = True 29 | TabOrder = 1 30 | end 31 | object ButtonRandom: TButton 32 | Left = 23 33 | Top = 51 34 | Width = 194 35 | Height = 25 36 | Caption = 'Generate Random Numbers' 37 | TabOrder = 2 38 | OnClick = ButtonRandomClick 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.RandFrame.pas: -------------------------------------------------------------------------------- 1 | unit SSLDemo.RandFrame; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 7 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.NetEncoding, 8 | System.IOUtils; 9 | 10 | type 11 | TRandomFrame = class(TFrame) 12 | EditSize: TEdit; 13 | EditResult: TEdit; 14 | ButtonRandom: TButton; 15 | LabelSize: TLabel; 16 | procedure ButtonRandomClick(Sender: TObject); 17 | private 18 | { Private declarations } 19 | public 20 | { Public declarations } 21 | end; 22 | 23 | implementation 24 | 25 | uses 26 | OpenSSL.RandUtils; 27 | 28 | {$R *.dfm} 29 | 30 | procedure TRandomFrame.ButtonRandomClick(Sender: TObject); 31 | var 32 | Buffer: TBytes; 33 | begin 34 | Buffer := TRandUtil.GetRandomBytes(StrToInt(EditSize.Text)); 35 | EditResult.Text := TNetEncoding.Base64.EncodeBytesToString(Buffer); 36 | end; 37 | 38 | end. 39 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.UnpackPKCS7Frame.dfm: -------------------------------------------------------------------------------- 1 | object UnpackPKCS7Frame: TUnpackPKCS7Frame 2 | Left = 0 3 | Top = 0 4 | Width = 440 5 | Height = 267 6 | TabOrder = 0 7 | DesignSize = ( 8 | 440 9 | 267) 10 | object lblPKCS7File: TLabel 11 | Left = 3 12 | Top = 19 13 | Width = 52 14 | Height = 13 15 | Caption = 'PKCS7 file:' 16 | end 17 | object lblOutputFile: TLabel 18 | Left = 3 19 | Top = 46 20 | Width = 55 21 | Height = 13 22 | Anchors = [akLeft, akTop, akRight] 23 | Caption = 'Output file:' 24 | end 25 | object edtInputFileName: TEdit 26 | Left = 60 27 | Top = 16 28 | Width = 380 29 | Height = 21 30 | Anchors = [akLeft, akTop, akRight] 31 | TabOrder = 0 32 | Text = 'edtInputFileName' 33 | end 34 | object edtOutputFileName: TEdit 35 | Left = 60 36 | Top = 43 37 | Width = 380 38 | Height = 21 39 | Anchors = [akLeft, akTop, akRight] 40 | TabOrder = 1 41 | Text = 'edtInputFileName' 42 | end 43 | object btnUnpack: TButton 44 | AlignWithMargins = True 45 | Left = 3 46 | Top = 70 47 | Width = 431 48 | Height = 25 49 | Caption = 'Unpack' 50 | TabOrder = 2 51 | OnClick = btnUnpackClick 52 | end 53 | object chkVerify: TCheckBox 54 | Left = 3 55 | Top = 120 56 | Width = 182 57 | Height = 17 58 | Caption = 'Verify (no output data provided)' 59 | Checked = True 60 | State = cbChecked 61 | TabOrder = 3 62 | end 63 | object chkNoVerify: TCheckBox 64 | Left = 221 65 | Top = 112 66 | Width = 213 67 | Height = 33 68 | Caption = 69 | 'No verify (do not verify the signers certificate of a signed mes' + 70 | 'sage)' 71 | Checked = True 72 | State = cbChecked 73 | TabOrder = 4 74 | WordWrap = True 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.UnpackPKCS7Frame.pas: -------------------------------------------------------------------------------- 1 | unit SSLDemo.UnpackPKCS7Frame; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 7 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 8 | 9 | type 10 | TUnpackPKCS7Frame = class(TFrame) 11 | lblPKCS7File: TLabel; 12 | edtInputFileName: TEdit; 13 | lblOutputFile: TLabel; 14 | edtOutputFileName: TEdit; 15 | btnUnpack: TButton; 16 | chkVerify: TCheckBox; 17 | chkNoVerify: TCheckBox; 18 | procedure btnUnpackClick(Sender: TObject); 19 | private 20 | { Private declarations } 21 | public 22 | constructor Create(AOwner: TComponent); override; 23 | end; 24 | 25 | implementation 26 | 27 | uses 28 | Winapi.ShellAPI, 29 | OpenSSL.SMIMEUtils; 30 | 31 | {$R *.dfm} 32 | 33 | procedure TUnpackPKCS7Frame.btnUnpackClick(Sender: TObject); 34 | var 35 | SMIME: TSMIMEUtil; 36 | Verify: Integer; 37 | InputStream, OutputStream: TMemoryStream; 38 | begin 39 | SMIME := TSMIMEUtil.Create; 40 | InputStream := TMemoryStream.Create; 41 | OutputStream := TMemoryStream.Create; 42 | try 43 | InputStream.LoadFromFile(edtInputFileName.Text); 44 | Verify := SMIME.Decrypt(InputStream, OutputStream, chkVerify.Checked, chkNoVerify.Checked); 45 | 46 | if chkVerify.Checked then 47 | begin 48 | if Verify = 1 then 49 | ShowMessage('Verification Successfull') 50 | else 51 | ShowMessage('Verification Failure') 52 | end; 53 | 54 | OutputStream.SaveToFile(edtOutputFileName.Text); 55 | ShellExecute(Handle, 'open', PChar(edtOutputFileName.Text), '', '', SW_SHOWDEFAULT); 56 | finally 57 | InputStream.Free; 58 | OutputStream.Free; 59 | SMIME.Free; 60 | end; 61 | end; 62 | 63 | constructor TUnpackPKCS7Frame.Create(AOwner: TComponent); 64 | var 65 | TestFolder :string; 66 | begin 67 | inherited; 68 | TestFolder := StringReplace(ExtractFilePath(ParamStr(0)), 'Samples\SSLDemo', 'TestData', [rfReplaceAll, rfIgnoreCase]); 69 | edtInputFileName.Text := TestFolder + 'TestPKCS7.pdf.p7m'; 70 | edtOutputFileName.Text := TestFolder + 'TestPKCS7-out.pdf'; 71 | end; 72 | 73 | end. 74 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.dpr: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | program SSLDemo; 23 | 24 | uses 25 | Vcl.Forms, 26 | SSLDemo.MainForm in 'SSLDemo.MainForm.pas' {MainForm}, 27 | SSLDemo.MainFrame in 'SSLDemo.MainFrame.pas' {MainFrame: TFrame}, 28 | SSLDemo.RSABufferFrame in 'SSLDemo.RSABufferFrame.pas' {RSABufferFrame: TFrame}, 29 | SSLDemo.EncFrame in 'SSLDemo.EncFrame.pas' {EncFrame: TFrame}, 30 | OpenSSL.Core in '..\..\Source\OpenSSL.Core.pas', 31 | OpenSSL.EncUtils in '..\..\Source\OpenSSL.EncUtils.pas', 32 | OpenSSL.libeay32 in '..\..\Source\OpenSSL.libeay32.pas', 33 | OpenSSL.RSAUtils in '..\..\Source\OpenSSL.RSAUtils.pas', 34 | OpenSSL.SMIMEUtils in '..\..\Source\OpenSSL.SMIMEUtils.pas', 35 | SSLDemo.RandFrame in 'SSLDemo.RandFrame.pas' {RandomFrame: TFrame}, 36 | SSLDemo.UnpackPKCS7Frame in 'SSLDemo.UnpackPKCS7Frame.pas' {UnpackPKCS7Frame: TFrame}, 37 | OpenSSL.RandUtils in '..\..\Source\OpenSSL.RandUtils.pas', 38 | SSLDemo.KeyPairFrame in 'SSLDemo.KeyPairFrame.pas' {KeyPairFrame: TFrame}; 39 | 40 | {$R *.res} 41 | 42 | begin 43 | ReportMemoryLeaksOnShutdown := True; 44 | Application.Initialize; 45 | Application.MainFormOnTaskbar := True; 46 | Application.CreateForm(TMainForm, MainForm); 47 | Application.Run; 48 | end. 49 | -------------------------------------------------------------------------------- /Samples/SSLDemo/SSLDemo.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/Samples/SSLDemo/SSLDemo.res -------------------------------------------------------------------------------- /Source/OpenSSL.Core.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit OpenSSL.Core; 23 | 24 | interface 25 | 26 | uses 27 | System.Classes, System.SysUtils, IdSSLOpenSSLHeaders, OpenSSL.libeay32; 28 | 29 | type 30 | TRASPadding = ( 31 | rpPKCS, // use PKCS#1 v1.5 padding (default), 32 | rpOAEP, // use PKCS#1 OAEP 33 | rpSSL, // use SSL v2 padding 34 | rpRAW // use no padding 35 | ); 36 | 37 | EOpenSSLError = Exception; 38 | 39 | EOpenSSLLibError = class(EOpenSSLError) 40 | private 41 | FErrorCode: Integer; 42 | public 43 | constructor Create(Code :Integer; const Msg: string); 44 | property ErrorCode :Integer read FErrorCode; 45 | end; 46 | 47 | TOpenSLLBase = class 48 | public 49 | class procedure CheckOpenSSLLibrary; static; 50 | constructor Create; virtual; 51 | end; 52 | 53 | const 54 | SALT_MAGIC: AnsiString = 'Salted__'; 55 | SALT_MAGIC_LEN: integer = 8; 56 | SALT_SIZE = 8; 57 | 58 | function GetOpenSSLErrorMessage: string; 59 | 60 | procedure RaiseOpenSSLError(const AMessage :string = ''); 61 | 62 | function EVP_GetSalt: TBytes; 63 | 64 | procedure EVP_GetKeyIV(APassword: TBytes; ACipher: PEVP_CIPHER; const ASalt: TBytes; out Key, IV: TBytes); overload; 65 | 66 | // Password will be encoded in UTF-8 if you want another encodig use the TBytes version 67 | procedure EVP_GetKeyIV(APassword: string; ACipher: PEVP_CIPHER; const ASalt: TBytes; out Key, IV: TBytes); overload; 68 | 69 | function Base64Encode(InputBuffer :TBytes) :TBytes; 70 | function Base64Decode(InputBuffer :TBytes) :TBytes; 71 | 72 | implementation 73 | 74 | function Base64Encode(InputBuffer :TBytes) :TBytes; 75 | var 76 | bio, b64 :PBIO; 77 | bdata :Pointer; 78 | datalen :Integer; 79 | begin 80 | b64 := BIO_new(BIO_f_base64()); 81 | bio := BIO_new(BIO_s_mem()); 82 | BIO_push(b64, bio); 83 | 84 | BIO_write(b64, @InputBuffer[0], Length(InputBuffer)); 85 | BIO_flush(b64); 86 | 87 | bdata := nil; 88 | datalen := OpenSSL.libeay32.BIO_get_mem_data(bio, @bdata); 89 | SetLength(Result, datalen); 90 | Move(bdata^, Result[0], datalen); 91 | 92 | BIO_free_all(b64); 93 | end; 94 | 95 | function Base64Decode(InputBuffer :TBytes) :TBytes; 96 | var 97 | bio, b64 :PBIO; 98 | datalen :Integer; 99 | begin 100 | b64 := BIO_new(BIO_f_base64()); 101 | bio := BIO_new_mem_buf(InputBuffer, Length(InputBuffer)); 102 | try 103 | BIO_push(b64, bio); 104 | 105 | SetLength(Result, Length(InputBuffer)); 106 | datalen := BIO_read(b64, @Result[0], Length(InputBuffer)); 107 | if datalen < 0 then 108 | RaiseOpenSSLError('Base64 error'); 109 | 110 | SetLength(Result, datalen); 111 | BIO_flush(b64); 112 | finally 113 | BIO_free_all(b64); 114 | end; 115 | end; 116 | 117 | function EVP_GetSalt: TBytes; 118 | begin 119 | SetLength(result, PKCS5_SALT_LEN); 120 | RAND_pseudo_bytes(@result[0], PKCS5_SALT_LEN); 121 | end; 122 | 123 | procedure EVP_GetKeyIV(APassword: TBytes; ACipher: PEVP_CIPHER; const ASalt: TBytes; out Key, IV: TBytes); 124 | begin 125 | SetLength(Key, EVP_MAX_KEY_LENGTH); 126 | SetLength(iv, EVP_MAX_IV_LENGTH); 127 | 128 | EVP_BytesToKey(ACipher,EVP_md5, @ASalt[0] ,@APassword[0] , Length(APassword),1, @Key[0], @IV[0]); 129 | end; 130 | 131 | procedure EVP_GetKeyIV(APassword: string; ACipher: PEVP_CIPHER; const ASalt: TBytes; out Key, IV: TBytes); 132 | begin 133 | EVP_GetKeyIV(TEncoding.UTF8.GetBytes(APassword), ACipher, ASalt, Key, IV); 134 | end; 135 | 136 | function GetOpenSSLErrorMessage: string; 137 | var 138 | ErrMsg: PAnsiChar; 139 | begin 140 | ErrMsg := ERR_error_string(ERR_get_error, nil); 141 | Result := string(AnsiString(ErrMsg)); 142 | end; 143 | 144 | procedure RaiseOpenSSLError(const AMessage :string); 145 | var 146 | ErrCode: Integer; 147 | ErrMsg, FullMsg: string; 148 | begin 149 | ErrCode := ERR_get_error; 150 | ErrMsg := string(AnsiString(ERR_error_string(ErrCode, nil))); 151 | if AMessage = '' then 152 | FullMsg := ErrMsg 153 | else 154 | FullMsg := AMessage + ': ' + ErrMsg; 155 | raise EOpenSSLLibError.Create(ErrCode, FullMsg); 156 | end; 157 | 158 | { TOpenSLLBase } 159 | 160 | constructor TOpenSLLBase.Create; 161 | begin 162 | inherited; 163 | CheckOpenSSLLibrary; 164 | end; 165 | 166 | class procedure TOpenSLLBase.CheckOpenSSLLibrary; 167 | begin 168 | if not LoadOpenSSLLibraryEx then 169 | raise EOpenSSLError.Create('Cannot open "OpenSSL" library'); 170 | end; 171 | 172 | { EOpenSSLLibError } 173 | 174 | constructor EOpenSSLLibError.Create(Code: Integer; const Msg: string); 175 | begin 176 | FErrorCode := Code; 177 | inherited Create(Msg); 178 | end; 179 | 180 | end. 181 | -------------------------------------------------------------------------------- /Source/OpenSSL.EncUtils.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | 23 | // enc - symmetric cipher routines 24 | // https://www.openssl.org/docs/manmaster/apps/enc.html 25 | 26 | unit OpenSSL.EncUtils; 27 | 28 | interface 29 | 30 | uses 31 | System.Classes, System.SysUtils, System.AnsiStrings, Generics.Collections, 32 | OpenSSL.libeay32, OpenSSL.Core, IdSSLOpenSSLHeaders; 33 | 34 | type 35 | TCipherName = string; 36 | 37 | TCipherProc = function : PEVP_CIPHER cdecl; 38 | 39 | TCipherInfo = record 40 | Name :TCipherName; 41 | Proc :TCipherProc; 42 | end; 43 | 44 | TCipherList = class(TThreadList) 45 | public 46 | function Count :Integer; 47 | function GetProc(const Name :TCipherName) :TCipherProc; 48 | end; 49 | 50 | TPassphraseType = (ptNone, ptPassword, ptKeys); 51 | 52 | TPassphrase = record 53 | private 54 | FType: TPassphraseType; 55 | FValue: TBytes; 56 | FKey: TBytes; 57 | FInitVector: TBytes; 58 | public 59 | class operator Implicit(const Value: string): TPassphrase; 60 | class operator Implicit(const Value: TBytes): TPassphrase; 61 | constructor Create(const Key, InitVector: TBytes); overload; 62 | constructor Create(const Password: string; Encoding: TEncoding); overload; 63 | end; 64 | 65 | TEncUtil = class(TOpenSLLBase) 66 | private 67 | class var 68 | FCipherList :TCipherList; 69 | class constructor Create; 70 | class destructor Destroy; 71 | private 72 | FPassphrase: TPassphrase; 73 | FBase64: Boolean; 74 | FCipherProc: TCipherProc; 75 | FCipher: TCipherName; 76 | procedure SetCipher(const Value: TCipherName); 77 | public 78 | class procedure RegisterCipher(const Name :TCipherName; Proc :TCipherProc); 79 | class procedure RegisterDefaultCiphers; 80 | class procedure SupportedCiphers(Ciphers :TStrings); 81 | public 82 | constructor Create; override; 83 | // will be encoded in UTF8 84 | property Passphrase :TPassphrase read FPassphrase write FPassphrase; 85 | 86 | // Encryption algorithm 87 | property Cipher :TCipherName read FCipher write SetCipher; 88 | 89 | // Apply a further base64 encoding to the encrypted buffer 90 | property UseBase64 :Boolean read FBase64 write FBase64; 91 | 92 | procedure Encrypt(InputStream :TStream; OutputStream :TStream); overload; 93 | procedure Encrypt(const InputFileName, OutputFileName :TFileName); overload; 94 | procedure Decrypt(InputStream :TStream; OutputStream :TStream); overload; 95 | procedure Decrypt(const InputFileName, OutputFileName :TFileName); overload; 96 | end; 97 | 98 | implementation 99 | 100 | { TEncUtil } 101 | 102 | procedure TEncUtil.Decrypt(InputStream, OutputStream: TStream); 103 | var 104 | Context :PEVP_CIPHER_CTX; 105 | Key :TBytes; 106 | InitVector :TBytes; 107 | 108 | InputBuffer :TBytes; 109 | OutputLen :Integer; 110 | OutputBuffer :TBytes; 111 | Base64Buffer :TBytes; 112 | 113 | Cipher: PEVP_CIPHER; 114 | Salt :TBytes; 115 | BuffStart :Integer; 116 | InputStart :Integer; 117 | begin 118 | if Assigned(FCipherProc) then 119 | Cipher := FCipherProc() 120 | else 121 | Cipher := EVP_aes_256_cbc(); 122 | 123 | if FBase64 then 124 | begin 125 | SetLength(Base64Buffer, InputStream.Size); 126 | InputStream.ReadBuffer(Base64Buffer[0], InputStream.Size); 127 | InputBuffer := Base64Decode(Base64Buffer); 128 | end 129 | else 130 | begin 131 | SetLength(InputBuffer, InputStream.Size); 132 | InputStream.ReadBuffer(InputBuffer[0], InputStream.Size); 133 | end; 134 | 135 | if FPassphrase.FType = ptPassword then 136 | begin 137 | SetLength(Salt, SALT_SIZE); 138 | if (AnsiString(TEncoding.ASCII.GetString(InputBuffer, 0, SALT_MAGIC_LEN)) = SALT_MAGIC) then 139 | begin 140 | if Length(FPassphrase.FValue) = 0 then 141 | raise EOpenSSLError.Create('Password needed'); 142 | 143 | Move(InputBuffer[SALT_MAGIC_LEN], Salt[0], SALT_SIZE); 144 | EVP_GetKeyIV(FPassphrase.FValue, Cipher, Salt, Key, InitVector); 145 | InputStart := SALT_MAGIC_LEN + SALT_SIZE; 146 | end 147 | else 148 | begin 149 | EVP_GetKeyIV(FPassphrase.FValue, Cipher, nil, Key, InitVector); 150 | InputStart := 0; 151 | end; 152 | end 153 | else if FPassphrase.FType = ptKeys then 154 | begin 155 | Key := FPassphrase.FKey; 156 | InitVector := FPassphrase.FInitVector; 157 | InputStart := 0; 158 | end 159 | else 160 | raise EOpenSSLError.Create('Password needed'); 161 | 162 | Context := EVP_CIPHER_CTX_new(); 163 | if Context = nil then 164 | RaiseOpenSSLError('Cannot initialize context'); 165 | 166 | try 167 | 168 | if EVP_DecryptInit_ex(Context, Cipher, nil, @Key[0], @InitVector[0]) <> 1 then 169 | RaiseOpenSSLError('Cannot initialize decryption process'); 170 | 171 | SetLength(OutputBuffer, InputStream.Size); 172 | BuffStart := 0; 173 | if OpenSSL.libeay32.EVP_DecryptUpdate(Context, @OutputBuffer[BuffStart], OutputLen, @InputBuffer[InputStart], Length(InputBuffer) - InputStart) <> 1 then 174 | RaiseOpenSSLError('Cannot decrypt'); 175 | Inc(BuffStart, OutputLen); 176 | 177 | if OpenSSL.libeay32.EVP_DecryptFinal_ex(Context, @OutputBuffer[BuffStart], OutputLen) <> 1 then 178 | RaiseOpenSSLError('Cannot finalize decryption process'); 179 | Inc(BuffStart, OutputLen); 180 | 181 | if BuffStart > 0 then 182 | OutputStream.WriteBuffer(OutputBuffer[0], BuffStart); 183 | 184 | finally 185 | EVP_CIPHER_CTX_free(Context); 186 | end; 187 | end; 188 | 189 | procedure TEncUtil.Encrypt(InputStream, OutputStream: TStream); 190 | var 191 | Context :PEVP_CIPHER_CTX; 192 | 193 | Key :TBytes; 194 | InitVector :TBytes; 195 | InputBuffer :TBytes; 196 | OutputLen :Integer; 197 | OutputBuffer :TBytes; 198 | Base64Buffer :TBytes; 199 | Salt :TBytes; 200 | 201 | cipher: PEVP_CIPHER; 202 | BlockSize :Integer; 203 | BuffStart :Integer; 204 | begin 205 | BuffStart := 0; 206 | SetLength(Salt, 0); 207 | 208 | if Assigned(FCipherProc) then 209 | cipher := FCipherProc() 210 | else 211 | cipher := EVP_aes_256_cbc(); 212 | 213 | if FPassphrase.FType = ptPassword then 214 | begin 215 | salt := EVP_GetSalt; 216 | EVP_GetKeyIV(FPassphrase.FValue, cipher, salt, key, InitVector); 217 | end 218 | else if FPassphrase.FType = ptKeys then 219 | begin 220 | Key := FPassphrase.FKey; 221 | InitVector := FPassphrase.FInitVector; 222 | end 223 | else 224 | raise EOpenSSLError.Create('Password needed'); 225 | 226 | SetLength(InputBuffer, InputStream.Size); 227 | InputStream.ReadBuffer(InputBuffer[0], InputStream.Size); 228 | 229 | Context := EVP_CIPHER_CTX_new(); 230 | if Context = nil then 231 | RaiseOpenSSLError('Cannot initialize context'); 232 | 233 | try 234 | if EVP_EncryptInit_ex(Context, cipher, nil, @Key[0], @InitVector[0]) <> 1 then 235 | RaiseOpenSSLError('Cannot initialize encryption process'); 236 | 237 | BlockSize := EVP_CIPHER_CTX_block_size(Context); 238 | if Length(salt) > 0 then 239 | begin 240 | SetLength(OutputBuffer, Length(InputBuffer) + BlockSize + SALT_MAGIC_LEN + PKCS5_SALT_LEN); 241 | Move(PAnsiChar(SALT_MAGIC)^, OutputBuffer[BuffStart], SALT_MAGIC_LEN); 242 | Inc(BuffStart, SALT_MAGIC_LEN); 243 | Move(salt[0], OutputBuffer[BuffStart], PKCS5_SALT_LEN); 244 | Inc(BuffStart, PKCS5_SALT_LEN); 245 | end 246 | else 247 | SetLength(OutputBuffer, Length(InputBuffer) + BlockSize); 248 | 249 | if EVP_EncryptUpdate(Context, @OutputBuffer[BuffStart], @OutputLen, @InputBuffer[0], Length(InputBuffer)) <> 1 then 250 | RaiseOpenSSLError('Cannot encrypt'); 251 | Inc(BuffStart, OutputLen); 252 | 253 | if EVP_EncryptFinal_ex(Context, @OutputBuffer[BuffStart], @OutputLen) <> 1 then 254 | RaiseOpenSSLError('Cannot finalize encryption process'); 255 | Inc(BuffStart, OutputLen); 256 | SetLength(OutputBuffer, BuffStart); 257 | 258 | if BuffStart > 0 then 259 | begin 260 | if FBase64 then 261 | begin 262 | Base64Buffer := Base64Encode(OutputBuffer); 263 | OutputStream.WriteBuffer(Base64Buffer[0], Length(Base64Buffer)); 264 | end 265 | else 266 | OutputStream.WriteBuffer(OutputBuffer[0], BuffStart); 267 | end; 268 | 269 | finally 270 | EVP_CIPHER_CTX_free(Context); 271 | end; 272 | end; 273 | 274 | procedure TEncUtil.Encrypt(const InputFileName, OutputFileName: TFileName); 275 | var 276 | InputFile, OutputFile :TStream; 277 | begin 278 | InputFile := TFileStream.Create(InputFileName, fmOpenRead); 279 | try 280 | OutputFile := TFileStream.Create(OutputFileName, fmCreate); 281 | try 282 | Encrypt(InputFile, OutputFile); 283 | finally 284 | OutputFile.Free; 285 | end; 286 | finally 287 | InputFile.Free; 288 | end; 289 | end; 290 | 291 | class procedure TEncUtil.RegisterCipher(const Name: TCipherName; 292 | Proc: TCipherProc); 293 | var 294 | Value :TCipherInfo; 295 | begin 296 | Value.Name := Name; 297 | Value.Proc := Proc; 298 | FCipherList.Add(Value); 299 | end; 300 | 301 | class procedure TEncUtil.RegisterDefaultCiphers; 302 | begin 303 | CheckOpenSSLLibrary; 304 | if FCipherList.Count = 0 then 305 | begin 306 | 307 | // AES 308 | RegisterCipher('AES', EVP_aes_256_cbc); 309 | RegisterCipher('AES-128', EVP_aes_128_cbc); 310 | RegisterCipher('AES-192', EVP_aes_192_cbc); 311 | RegisterCipher('AES-256', EVP_aes_256_cbc); 312 | 313 | RegisterCipher('AES-CBC', EVP_aes_256_cbc); 314 | RegisterCipher('AES-128-CBC', EVP_aes_128_cbc); 315 | RegisterCipher('AES-192-CBC', EVP_aes_192_cbc); 316 | RegisterCipher('AES-256-CBC', EVP_aes_256_cbc); 317 | 318 | RegisterCipher('AES-CFB', EVP_aes_256_cfb128); 319 | RegisterCipher('AES-128-CFB', EVP_aes_128_cfb128); 320 | RegisterCipher('AES-192-CFB', EVP_aes_192_cfb128); 321 | RegisterCipher('AES-256-CFB', EVP_aes_256_cfb128); 322 | 323 | RegisterCipher('AES-CFB1', EVP_aes_256_cfb1); 324 | RegisterCipher('AES-128-CFB1', EVP_aes_128_cfb1); 325 | RegisterCipher('AES-192-CFB1', EVP_aes_192_cfb1); 326 | RegisterCipher('AES-256-CFB1', EVP_aes_256_cfb1); 327 | 328 | RegisterCipher('AES-CFB8', EVP_aes_256_cfb8); 329 | RegisterCipher('AES-128-CFB8', EVP_aes_128_cfb8); 330 | RegisterCipher('AES-192-CFB8', EVP_aes_192_cfb8); 331 | RegisterCipher('AES-256-CFB8', EVP_aes_256_cfb8); 332 | 333 | RegisterCipher('AES-ECB', EVP_aes_256_ecb); 334 | RegisterCipher('AES-128-ECB', EVP_aes_128_ecb); 335 | RegisterCipher('AES-192-ECB', EVP_aes_192_ecb); 336 | RegisterCipher('AES-256-ECB', EVP_aes_256_ecb); 337 | 338 | RegisterCipher('AES-OFB', EVP_aes_256_ofb); 339 | RegisterCipher('AES-128-OFB', EVP_aes_128_ofb); 340 | RegisterCipher('AES-192-OFB', EVP_aes_192_ofb); 341 | RegisterCipher('AES-256-OFB', EVP_aes_256_ofb); 342 | 343 | // Blowfish 344 | RegisterCipher('BF', EVP_bf_cbc); 345 | RegisterCipher('BF-CBC', EVP_bf_cbc); 346 | RegisterCipher('BF-ECB', EVP_bf_ecb); 347 | RegisterCipher('BF-CBF', EVP_bf_cfb64); 348 | RegisterCipher('BF-OFB', EVP_bf_ofb); 349 | 350 | // DES 351 | RegisterCipher('DES-CBC', EVP_des_cbc); 352 | RegisterCipher('DES', EVP_des_cbc); 353 | RegisterCipher('DES-CFB', EVP_des_cfb64); 354 | RegisterCipher('DES-OFB', EVP_des_ofb); 355 | RegisterCipher('DES-ECB', EVP_des_ecb); 356 | 357 | // Two key triple DES EDE 358 | RegisterCipher('DES-EDE-CBC', EVP_des_ede_cbc); 359 | RegisterCipher('DES-EDE', EVP_des_ede); 360 | RegisterCipher('DES-EDE-CFB', EVP_des_ede_cfb64); 361 | RegisterCipher('DES-EDE-OFB', EVP_des_ede_ofb); 362 | 363 | // Two key triple DES EDE 364 | RegisterCipher('DES-EDE3-CBC', EVP_des_ede3_cbc); 365 | RegisterCipher('DES-EDE3', EVP_des_ede3); 366 | RegisterCipher('DES3', EVP_des_ede3); 367 | RegisterCipher('DES-EDE3-CFB', EVP_des_ede3_cfb64); 368 | RegisterCipher('DES-EDE3-OFB', EVP_des_ede3_ofb); 369 | 370 | // DESX algorithm 371 | RegisterCipher('DESX', EVP_desx_cbc); 372 | 373 | // IDEA algorithm 374 | RegisterCipher('IDEA-CBC', EVP_idea_cbc); 375 | RegisterCipher('IDEA', EVP_idea_cbc); 376 | RegisterCipher('IDEA-CFB', EVP_idea_cfb64); 377 | RegisterCipher('IDEA-ECB', EVP_idea_ecb); 378 | RegisterCipher('IDEA-OFB', EVP_idea_ofb); 379 | 380 | // RC2 381 | RegisterCipher('RC2-CBC', EVP_rc2_cbc); 382 | RegisterCipher('RC2', EVP_rc2_cbc); 383 | RegisterCipher('RC2-CFB', EVP_rc2_cfb64); 384 | RegisterCipher('RC2-ECB', EVP_rc2_ecb); 385 | RegisterCipher('RC2-OFB', EVP_rc2_ofb); 386 | RegisterCipher('RC2-64-CBC', nil); 387 | RegisterCipher('RC2-40-CBC', nil); 388 | 389 | // RC4 390 | RegisterCipher('RC4', EVP_rc4); 391 | RegisterCipher('RC4-40', EVP_rc4_40); 392 | 393 | end; 394 | end; 395 | 396 | procedure TEncUtil.SetCipher(const Value: TCipherName); 397 | begin 398 | FCipherProc := FCipherList.GetProc(Value); 399 | if @FCipherProc = nil then 400 | raise EOpenSSLError.CreateFmt('Cipher not found: "%s"', [Value]); 401 | FCipher := Value; 402 | end; 403 | 404 | class procedure TEncUtil.SupportedCiphers(Ciphers: TStrings); 405 | var 406 | CipherInfo :TCipherInfo; 407 | LocalCipherList :TList; 408 | begin 409 | RegisterDefaultCiphers; 410 | Ciphers.Clear; 411 | LocalCipherList := FCipherList.LockList; 412 | try 413 | for CipherInfo in LocalCipherList do 414 | Ciphers.Add(CipherInfo.Name); 415 | finally 416 | FCipherList.UnlockList; 417 | end; 418 | end; 419 | 420 | class constructor TEncUtil.Create; 421 | begin 422 | FCipherList := TCipherList.Create; 423 | end; 424 | 425 | constructor TEncUtil.Create; 426 | begin 427 | inherited Create; 428 | TEncUtil.RegisterDefaultCiphers; 429 | end; 430 | 431 | procedure TEncUtil.Decrypt(const InputFileName, OutputFileName: TFileName); 432 | var 433 | InputFile, OutputFile :TStream; 434 | begin 435 | InputFile := TFileStream.Create(InputFileName, fmOpenRead); 436 | try 437 | OutputFile := TFileStream.Create(OutputFileName, fmCreate); 438 | try 439 | Decrypt(InputFile, OutputFile); 440 | finally 441 | OutputFile.Free; 442 | end; 443 | finally 444 | InputFile.Free; 445 | end; 446 | end; 447 | 448 | class destructor TEncUtil.Destroy; 449 | begin 450 | FCipherList.Free; 451 | end; 452 | 453 | { TCipherList } 454 | 455 | function TCipherList.Count: Integer; 456 | var 457 | LocalCipherList :TList; 458 | begin 459 | LocalCipherList := LockList; 460 | try 461 | Result := LocalCipherList.Count; 462 | finally 463 | UnlockList; 464 | end; 465 | end; 466 | 467 | function TCipherList.GetProc(const Name: TCipherName): TCipherProc; 468 | var 469 | CipherInfo :TCipherInfo; 470 | LocalCipherList :TList; 471 | begin 472 | Result := nil; 473 | LocalCipherList := LockList; 474 | try 475 | for CipherInfo in LocalCipherList do 476 | if CipherInfo.Name = Name then 477 | begin 478 | Result := CipherInfo.Proc; 479 | Break; 480 | end; 481 | finally 482 | UnlockList; 483 | end; 484 | end; 485 | 486 | { TPassphrase } 487 | 488 | constructor TPassphrase.Create(const Key, InitVector: TBytes); 489 | begin 490 | FType := ptKeys; 491 | FKey := Key; 492 | FInitVector := InitVector; 493 | end; 494 | 495 | constructor TPassphrase.Create(const Password: string; Encoding: TEncoding); 496 | begin 497 | FType := ptPassword; 498 | FValue := Encoding.GetBytes(Password); 499 | end; 500 | 501 | class operator TPassphrase.Implicit(const Value: string): TPassphrase; 502 | begin 503 | Result.FType := ptPassword; 504 | Result.FValue := TEncoding.UTF8.GetBytes(Value); 505 | end; 506 | 507 | class operator TPassphrase.Implicit(const Value: TBytes): TPassphrase; 508 | begin 509 | Result.FType := ptPassword; 510 | Result.FValue := Value; 511 | end; 512 | 513 | end. 514 | -------------------------------------------------------------------------------- /Source/OpenSSL.RSAUtils.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit OpenSSL.RSAUtils; 23 | 24 | interface 25 | 26 | uses 27 | System.Classes, System.SysUtils, System.AnsiStrings, OpenSSL.libeay32, 28 | OpenSSL.Core, IdSSLOpenSSLHeaders; 29 | 30 | type 31 | TX509Cerificate = class; 32 | 33 | TPassphraseEvent = procedure (Sender :TObject; var Passphrase :string) of object; 34 | 35 | TPublicKeyFormat = (kfDefault, kfRSAPublicKey); 36 | TPrivateKeyFormat = (kpDefault, kpRSAPrivateKey); 37 | 38 | // RSA public key 39 | TCustomRSAPublicKey = class(TOpenSLLBase) 40 | private 41 | FBuffer: TBytes; 42 | FCerificate :TX509Cerificate; 43 | protected 44 | function GetRSA :PRSA; virtual; abstract; 45 | procedure FreeRSA; virtual; abstract; 46 | public 47 | constructor Create; override; 48 | destructor Destroy; override; 49 | function Print: string; 50 | function IsValid :Boolean; 51 | procedure LoadFromFile(const FileName :string; AFormat: TPublicKeyFormat = kfDefault); virtual; 52 | procedure LoadFromStream(AStream :TStream; AFormat: TPublicKeyFormat = kfDefault); virtual; 53 | procedure LoadFromCertificate(Cerificate :TX509Cerificate); 54 | procedure SaveToFile(const FileName :string; AFormat: TPublicKeyFormat = kfDefault); virtual; 55 | procedure SaveToStream(AStream :TStream; AFormat: TPublicKeyFormat = kfDefault); virtual; 56 | end; 57 | 58 | TRSAPublicKey = class(TCustomRSAPublicKey) 59 | private 60 | FRSA :PRSA; 61 | protected 62 | procedure FreeRSA; override; 63 | function GetRSA :PRSA; override; 64 | public 65 | constructor Create; override; 66 | procedure LoadFromStream(AStream :TStream; AFormat: TPublicKeyFormat = kfDefault); override; 67 | end; 68 | 69 | // RSA private key 70 | TCustomRSAPrivateKey = class(TOpenSLLBase) 71 | private 72 | FBuffer: TBytes; 73 | FOnNeedPassphrase: TPassphraseEvent; 74 | protected 75 | function GetRSA :PRSA; virtual; abstract; 76 | procedure FreeRSA; virtual; abstract; 77 | public 78 | constructor Create; override; 79 | destructor Destroy; override; 80 | function IsValid :Boolean; 81 | function Print: string; 82 | procedure LoadFromFile(const FileName :string; AFormat: TPrivateKeyFormat = kpDefault); virtual; 83 | procedure LoadFromStream(AStream :TStream; AFormat: TPrivateKeyFormat = kpDefault); virtual; 84 | procedure SaveToFile(const FileName :string; AFormat: TPrivateKeyFormat = kpDefault); virtual; 85 | procedure SaveToStream(AStream :TStream; AFormat: TPrivateKeyFormat = kpDefault); virtual; 86 | property OnNeedPassphrase :TPassphraseEvent read FOnNeedPassphrase write FOnNeedPassphrase; 87 | end; 88 | 89 | TRSAPrivateKey = class(TCustomRSAPrivateKey) 90 | private 91 | FRSA :PRSA; 92 | protected 93 | procedure FreeRSA; override; 94 | function GetRSA :PRSA; override; 95 | public 96 | constructor Create; override; 97 | procedure LoadFromStream(AStream :TStream; AFormat: TPrivateKeyFormat = kpDefault); override; 98 | end; 99 | 100 | // certificate containing an RSA public key 101 | TX509Cerificate = class(TOpenSLLBase) 102 | private 103 | FBuffer: TBytes; 104 | FPublicRSA :PRSA; 105 | FX509 :pX509; 106 | procedure FreeRSA; 107 | procedure FreeX509; 108 | function GetPublicRSA :PRSA; 109 | public 110 | constructor Create; override; 111 | destructor Destroy; override; 112 | 113 | function IsValid :Boolean; 114 | function Print: string; 115 | procedure LoadFromFile(const FileName :string); 116 | procedure LoadFromStream(AStream :TStream); 117 | end; 118 | 119 | TRSAKeyPair = class(TOpenSLLBase) 120 | private 121 | FRSA: PRSA; 122 | FPrivateKey: TCustomRSAPrivateKey; 123 | FPublicKey: TCustomRSAPublicKey; 124 | procedure FreeRSA; 125 | public 126 | property PrivateKey: TCustomRSAPrivateKey read FPrivateKey; 127 | property PublicKey: TCustomRSAPublicKey read FPublicKey; 128 | 129 | procedure GenerateKey; overload; 130 | procedure GenerateKey(KeySize: Integer); overload; 131 | constructor Create; override; 132 | destructor Destroy; override; 133 | end; 134 | 135 | TRSAUtil = class(TOpenSLLBase) 136 | private 137 | FPublicKey :TCustomRSAPublicKey; 138 | FPrivateKey: TCustomRSAPrivateKey; 139 | FOwnedPrivateKey: TCustomRSAPrivateKey; 140 | FOwnedPublicKey: TCustomRSAPublicKey; 141 | procedure SetPrivateKey(const Value: TCustomRSAPrivateKey); 142 | procedure SetPublicKey(const Value: TCustomRSAPublicKey); 143 | public 144 | constructor Create; override; 145 | destructor Destroy; override; 146 | procedure PublicEncrypt(InputStream :TStream; OutputStream :TStream; Padding :TRASPadding = rpPKCS); overload; 147 | procedure PublicEncrypt(const InputFileName, OutputFileName :TFileName; Padding :TRASPadding = rpPKCS); overload; 148 | procedure PrivateDecrypt(InputStream :TStream; OutputStream :TStream; Padding :TRASPadding = rpPKCS); overload; 149 | procedure PrivateDecrypt(const InputFileName, OutputFileName :TFileName; Padding :TRASPadding = rpPKCS); overload; 150 | 151 | property PublicKey :TCustomRSAPublicKey read FPublicKey write SetPublicKey; 152 | property PrivateKey :TCustomRSAPrivateKey read FPrivateKey write SetPrivateKey; 153 | end; 154 | 155 | implementation 156 | 157 | type 158 | TRSAKeyPairPrivateKey = class(TCustomRSAPrivateKey) 159 | private 160 | FKeyPair: TRSAKeyPair; 161 | protected 162 | procedure FreeRSA; override; 163 | function GetRSA :PRSA; override; 164 | public 165 | constructor Create(KeyPair: TRSAKeyPair); reintroduce; 166 | end; 167 | 168 | TRSAKeyPairPublicKey = class(TCustomRSAPublicKey) 169 | private 170 | FKeyPair: TRSAKeyPair; 171 | protected 172 | procedure FreeRSA; override; 173 | function GetRSA :PRSA; override; 174 | public 175 | constructor Create(KeyPair: TRSAKeyPair); reintroduce; 176 | end; 177 | 178 | const 179 | PaddingMap : array [TRASPadding] of Integer = (RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_SSLV23_PADDING, RSA_NO_PADDING); 180 | 181 | // rwflag is a flag set to 0 when reading and 1 when writing 182 | // The u parameter has the same value as the u parameter passed to the PEM routines 183 | function ReadKeyCallback(buf: PAnsiChar; buffsize: integer; rwflag: integer; u: pointer): integer; cdecl; 184 | var 185 | Len :Integer; 186 | Password :string; 187 | PrivateKey :TCustomRSAPrivateKey; 188 | begin 189 | Result := 0; 190 | if Assigned(u) then 191 | begin 192 | PrivateKey := TCustomRSAPrivateKey(u); 193 | if Assigned(PrivateKey.FOnNeedPassphrase) then 194 | begin 195 | PrivateKey.FOnNeedPassphrase(PrivateKey, Password); 196 | if Length(Password) < buffsize then 197 | Len := Length(Password) 198 | else 199 | Len := buffsize; 200 | System.AnsiStrings.StrPLCopy(buf, AnsiString(Password), Len); 201 | Result := Len; 202 | end; 203 | end; 204 | end; 205 | 206 | 207 | procedure TRSAUtil.PublicEncrypt(InputStream, OutputStream: TStream; Padding: TRASPadding); 208 | var 209 | InputBuffer :TBytes; 210 | OutputBuffer :TBytes; 211 | RSAOutLen :Integer; 212 | begin 213 | if not PublicKey.IsValid then 214 | raise Exception.Create('Public key not assigned'); 215 | 216 | SetLength(InputBuffer, InputStream.Size); 217 | InputStream.ReadBuffer(InputBuffer[0], InputStream.Size); 218 | 219 | RSAOutLen := RSA_size(FPublicKey.GetRSA); 220 | SetLength(OutputBuffer, RSAOutLen); 221 | 222 | RSAOutLen := RSA_public_encrypt(Length(InputBuffer), PByte(InputBuffer), PByte(OutputBuffer), FPublicKey.GetRSA, PaddingMap[Padding]); 223 | 224 | if RSAOutLen <= 0 then 225 | RaiseOpenSSLError('RSA operation error'); 226 | 227 | OutputStream.Write(OutputBuffer[0], RSAOutLen); 228 | end; 229 | 230 | constructor TRSAUtil.Create; 231 | begin 232 | inherited; 233 | FOwnedPublicKey := TRSAPublicKey.Create; 234 | FOwnedPrivateKey := TRSAPrivateKey.Create; 235 | 236 | FPrivateKey := FOwnedPrivateKey; 237 | FPublicKey := FOwnedPublicKey; 238 | end; 239 | 240 | destructor TRSAUtil.Destroy; 241 | begin 242 | FOwnedPublicKey.Free; 243 | FOwnedPrivateKey.Free; 244 | inherited; 245 | end; 246 | 247 | procedure TRSAUtil.PrivateDecrypt(InputStream, OutputStream: TStream; 248 | Padding: TRASPadding); 249 | var 250 | InputBuffer :TBytes; 251 | OutputBuffer :TBytes; 252 | RSAOutLen :Integer; 253 | begin 254 | if not PrivateKey.IsValid then 255 | raise Exception.Create('Private key not assigned'); 256 | 257 | SetLength(InputBuffer, InputStream.Size); 258 | InputStream.ReadBuffer(InputBuffer[0], InputStream.Size); 259 | 260 | RSAOutLen := RSA_size(FPrivateKey.GetRSA); 261 | SetLength(OutputBuffer, RSAOutLen); 262 | 263 | RSAOutLen := RSA_private_decrypt(Length(InputBuffer), PByte(InputBuffer), PByte(OutputBuffer), FPrivateKey.GetRSA, PaddingMap[Padding]); 264 | 265 | if RSAOutLen <= 0 then 266 | RaiseOpenSSLError('RSA operation error'); 267 | 268 | OutputStream.Write(OutputBuffer[0], RSAOutLen); 269 | end; 270 | 271 | procedure TRSAUtil.PrivateDecrypt(const InputFileName, 272 | OutputFileName: TFileName; Padding: TRASPadding); 273 | var 274 | InputFile, OutputFile :TStream; 275 | begin 276 | InputFile := TFileStream.Create(InputFileName, fmOpenRead); 277 | try 278 | OutputFile := TFileStream.Create(OutputFileName, fmCreate); 279 | try 280 | PrivateDecrypt(InputFile, OutputFile, Padding); 281 | finally 282 | OutputFile.Free; 283 | end; 284 | finally 285 | InputFile.Free; 286 | end; 287 | end; 288 | 289 | procedure TRSAUtil.PublicEncrypt(const InputFileName, OutputFileName: TFileName; 290 | Padding: TRASPadding); 291 | var 292 | InputFile, OutputFile :TStream; 293 | begin 294 | InputFile := TFileStream.Create(InputFileName, fmOpenRead); 295 | try 296 | OutputFile := TFileStream.Create(OutputFileName, fmCreate); 297 | try 298 | PublicEncrypt(InputFile, OutputFile, Padding); 299 | finally 300 | OutputFile.Free; 301 | end; 302 | finally 303 | InputFile.Free; 304 | end; 305 | end; 306 | 307 | procedure TRSAUtil.SetPrivateKey(const Value: TCustomRSAPrivateKey); 308 | begin 309 | FPrivateKey := Value; 310 | end; 311 | 312 | procedure TRSAUtil.SetPublicKey(const Value: TCustomRSAPublicKey); 313 | begin 314 | FPublicKey := Value; 315 | end; 316 | 317 | { TX509Cerificate } 318 | 319 | constructor TX509Cerificate.Create; 320 | begin 321 | inherited; 322 | FPublicRSA := nil; 323 | end; 324 | 325 | destructor TX509Cerificate.Destroy; 326 | begin 327 | FreeRSA; 328 | FreeX509; 329 | inherited; 330 | end; 331 | 332 | procedure TX509Cerificate.FreeRSA; 333 | begin 334 | if FPublicRSA <> nil then 335 | begin 336 | RSA_free(FPublicRSA); 337 | FPublicRSA := nil; 338 | end; 339 | end; 340 | 341 | procedure TX509Cerificate.FreeX509; 342 | begin 343 | if FX509 <> nil then 344 | X509_free(FX509); 345 | end; 346 | 347 | function TX509Cerificate.GetPublicRSA: PRSA; 348 | var 349 | Key: pEVP_PKEY; 350 | begin 351 | if not Assigned(FPublicRSA) then 352 | begin 353 | Key := X509_get_pubkey(FX509); 354 | try 355 | FPublicRSA := EVP_PKEY_get1_RSA(Key); 356 | if not Assigned(FPublicRSA) then 357 | RaiseOpenSSLError('X501 unable to read public key'); 358 | finally 359 | EVP_PKEY_free(Key); 360 | end; 361 | end; 362 | 363 | Result := FPublicRSA; 364 | end; 365 | 366 | function TX509Cerificate.IsValid: Boolean; 367 | begin 368 | Result := Assigned(FX509); 369 | end; 370 | 371 | function TX509Cerificate.Print: string; 372 | var 373 | bp: PBIO; 374 | begin 375 | bp := BIO_new(BIO_s_mem()); 376 | try 377 | if RSA_print(bp, GetPublicRSA, 0) = 0 then 378 | RaiseOpenSSLError('RSA_print'); 379 | Result := BIO_to_string(bp); 380 | finally 381 | BIO_free(bp); 382 | end; 383 | end; 384 | 385 | procedure TX509Cerificate.LoadFromFile(const FileName: string); 386 | var 387 | Stream: TStream; 388 | begin 389 | Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 390 | try 391 | LoadFromStream(Stream); 392 | finally 393 | Stream.Free; 394 | end; 395 | end; 396 | 397 | procedure TX509Cerificate.LoadFromStream(AStream: TStream); 398 | var 399 | KeyFile :pBIO; 400 | begin 401 | FreeRSA; 402 | FreeX509; 403 | 404 | SetLength(FBuffer, AStream.Size); 405 | AStream.ReadBuffer(FBuffer[0], AStream.Size); 406 | KeyFile := BIO_new_mem_buf(FBuffer, Length(FBuffer)); 407 | if KeyFile = nil then 408 | RaiseOpenSSLError('X509 load stream error'); 409 | try 410 | FX509 := PEM_read_bio_X509(KeyFile, nil, nil, nil); 411 | if not Assigned(FX509) then 412 | RaiseOpenSSLError('X509 load certificate error'); 413 | finally 414 | BIO_free(KeyFile); 415 | end; 416 | end; 417 | 418 | { TCustomRSAPrivateKey } 419 | 420 | constructor TCustomRSAPrivateKey.Create; 421 | begin 422 | inherited; 423 | end; 424 | 425 | destructor TCustomRSAPrivateKey.Destroy; 426 | begin 427 | FreeRSA; 428 | inherited; 429 | end; 430 | 431 | function TCustomRSAPrivateKey.IsValid: Boolean; 432 | begin 433 | Result := GetRSA <> nil; 434 | end; 435 | 436 | procedure TCustomRSAPrivateKey.LoadFromFile(const FileName: string; AFormat: TPrivateKeyFormat = kpDefault); 437 | var 438 | Stream: TStream; 439 | begin 440 | Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 441 | try 442 | LoadFromStream(Stream, AFormat); 443 | finally 444 | Stream.Free; 445 | end; 446 | end; 447 | 448 | procedure TCustomRSAPrivateKey.LoadFromStream(AStream: TStream; AFormat: TPrivateKeyFormat = kpDefault); 449 | begin 450 | raise EOpenSSLError.Create('Cannot load private key'); 451 | end; 452 | 453 | function TCustomRSAPrivateKey.Print: string; 454 | var 455 | bp: PBIO; 456 | begin 457 | bp := BIO_new(BIO_s_mem()); 458 | try 459 | if RSA_print(bp, GetRSA, 0) = 0 then 460 | RaiseOpenSSLError('RSA_print'); 461 | Result := BIO_to_string(bp); 462 | finally 463 | BIO_free(bp); 464 | end; 465 | end; 466 | 467 | procedure TCustomRSAPrivateKey.SaveToFile(const FileName: string; 468 | AFormat: TPrivateKeyFormat); 469 | var 470 | Stream: TStream; 471 | begin 472 | Stream := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite); 473 | try 474 | SaveToStream(Stream, AFormat); 475 | finally 476 | Stream.Free; 477 | end; 478 | end; 479 | 480 | procedure TCustomRSAPrivateKey.SaveToStream(AStream: TStream; 481 | AFormat: TPrivateKeyFormat); 482 | var 483 | PrivateKey: PBIO; 484 | KeyLength: Integer; 485 | Buffer: TBytes; 486 | pKey: pEVP_PKEY; 487 | begin 488 | PrivateKey := BIO_new(BIO_s_mem); 489 | try 490 | case AFormat of 491 | kpDefault: begin 492 | pKey := EVP_PKEY_new(); // TODO: check value 493 | try 494 | EVP_PKEY_set1_RSA(pKey, GetRSA); // TODO: check value 495 | PEM_write_bio_PrivateKey(PrivateKey, pKey, nil, nil, 0, nil, nil); 496 | KeyLength := BIO_pending(PrivateKey); 497 | finally 498 | EVP_PKEY_free(pKey); 499 | end; 500 | end; 501 | kpRSAPrivateKey: begin 502 | PEM_write_bio_RSAPrivateKey(PrivateKey, GetRSA, nil, nil, 0, nil, nil); 503 | KeyLength := BIO_pending(PrivateKey); 504 | end; 505 | else 506 | raise EOpenSSLError.Create('Invalid format'); 507 | end; 508 | 509 | SetLength(Buffer, KeyLength); 510 | BIO_read(PrivateKey, @Buffer[0], KeyLength); 511 | finally 512 | BIO_free(PrivateKey); 513 | end; 514 | AStream.Write(Buffer[0], Length(Buffer)); 515 | end; 516 | 517 | { TCustomRSAPublicKey } 518 | 519 | constructor TCustomRSAPublicKey.Create; 520 | begin 521 | inherited; 522 | end; 523 | 524 | destructor TCustomRSAPublicKey.Destroy; 525 | begin 526 | FreeRSA; 527 | inherited; 528 | end; 529 | 530 | function TCustomRSAPublicKey.IsValid: Boolean; 531 | begin 532 | Result := GetRSA <> nil; 533 | end; 534 | 535 | procedure TCustomRSAPublicKey.LoadFromCertificate(Cerificate: TX509Cerificate); 536 | begin 537 | FCerificate := Cerificate; 538 | end; 539 | 540 | procedure TCustomRSAPublicKey.LoadFromFile(const FileName: string; AFormat: TPublicKeyFormat = kfDefault); 541 | var 542 | Stream: TStream; 543 | begin 544 | Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); 545 | try 546 | LoadFromStream(Stream, AFormat); 547 | finally 548 | Stream.Free; 549 | end; 550 | end; 551 | 552 | procedure TCustomRSAPublicKey.LoadFromStream(AStream: TStream; AFormat: TPublicKeyFormat); 553 | begin 554 | raise EOpenSSLError.Create('Cannot load private key'); 555 | end; 556 | 557 | function TCustomRSAPublicKey.Print: string; 558 | var 559 | bp: PBIO; 560 | begin 561 | bp := BIO_new(BIO_s_mem()); 562 | try 563 | if RSA_print(bp, GetRSA, 0) = 0 then 564 | RaiseOpenSSLError('RSA_print'); 565 | Result := BIO_to_string(bp); 566 | finally 567 | BIO_free(bp); 568 | end; 569 | end; 570 | 571 | procedure TCustomRSAPublicKey.SaveToFile(const FileName: string; 572 | AFormat: TPublicKeyFormat); 573 | var 574 | Stream: TStream; 575 | begin 576 | Stream := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite); 577 | try 578 | SaveToStream(Stream, AFormat); 579 | finally 580 | Stream.Free; 581 | end; 582 | end; 583 | 584 | procedure TCustomRSAPublicKey.SaveToStream(AStream: TStream; 585 | AFormat: TPublicKeyFormat); 586 | var 587 | PublicKey: PBIO; 588 | KeyLength: Integer; 589 | Buffer: TBytes; 590 | pKey: pEVP_PKEY; 591 | begin 592 | PublicKey := BIO_new(BIO_s_mem); 593 | try 594 | 595 | case AFormat of 596 | kfDefault: begin 597 | pKey := EVP_PKEY_new(); // TODO: check value 598 | try 599 | EVP_PKEY_set1_RSA(pKey, GetRSA); // TODO: check value 600 | PEM_write_bio_PUBKEY(PublicKey, pKey); 601 | KeyLength := BIO_pending(PublicKey); 602 | finally 603 | EVP_PKEY_free(pKey); 604 | end; 605 | end; 606 | kfRSAPublicKey: begin 607 | PEM_write_bio_RSAPublicKey(PublicKey, GetRSA); 608 | KeyLength := BIO_pending(PublicKey); 609 | end; 610 | else 611 | raise EOpenSSLError.Create('Invalid format'); 612 | end; 613 | 614 | SetLength(Buffer, KeyLength); 615 | BIO_read(PublicKey, @Buffer[0], KeyLength); 616 | finally 617 | BIO_free(PublicKey); 618 | end; 619 | AStream.WriteBuffer(Buffer[0], Length(Buffer)); 620 | end; 621 | 622 | { TRSAKeyPair } 623 | 624 | constructor TRSAKeyPair.Create; 625 | begin 626 | inherited; 627 | FPrivateKey := TRSAKeyPairPrivateKey.Create(Self); 628 | FPublicKey := TRSAKeyPairPublicKey.Create(Self); 629 | end; 630 | 631 | destructor TRSAKeyPair.Destroy; 632 | begin 633 | FreeRSA; 634 | FPrivateKey.Free; 635 | FPublicKey.Free; 636 | inherited; 637 | end; 638 | 639 | procedure TRSAKeyPair.FreeRSA; 640 | begin 641 | if FRSA <> nil then 642 | begin 643 | RSA_free(FRSA); 644 | FRSA := nil; 645 | end; 646 | end; 647 | 648 | // Thanks for Allen Drennan 649 | // https://stackoverflow.com/questions/55229772/using-openssl-to-generate-keypairs/55239810#55239810 650 | procedure TRSAKeyPair.GenerateKey(KeySize: Integer); 651 | var 652 | Bignum: PBIGNUM; 653 | begin 654 | FreeRSA; 655 | 656 | Bignum := BN_new(); 657 | try 658 | if BN_set_word(Bignum, RSA_F4) = 1 then 659 | begin 660 | FRSA := RSA_new; 661 | try 662 | if BN_set_word(Bignum, RSA_F4) = 0 then 663 | RaiseOpenSSLError('BN_set_word'); 664 | 665 | if RSA_generate_key_ex(FRSA, KeySize, Bignum, nil) = 0 then 666 | RaiseOpenSSLError('RSA_generate_key_ex'); 667 | except 668 | FreeRSA; 669 | raise; 670 | end; 671 | end; 672 | finally 673 | BN_free(Bignum); 674 | end; 675 | end; 676 | 677 | procedure TRSAKeyPair.GenerateKey; 678 | const 679 | DefaultKeySize = 2048; 680 | begin 681 | GenerateKey(DefaultKeySize); 682 | end; 683 | 684 | { TRSAPrivateKey } 685 | 686 | constructor TRSAPrivateKey.Create; 687 | begin 688 | inherited; 689 | FRSA := nil; 690 | end; 691 | 692 | procedure TRSAPrivateKey.FreeRSA; 693 | begin 694 | if FRSA <> nil then 695 | begin 696 | RSA_free(FRSA); 697 | FRSA := nil; 698 | end; 699 | end; 700 | 701 | function TRSAPrivateKey.GetRSA: PRSA; 702 | begin 703 | Result := FRSA; 704 | end; 705 | 706 | procedure TRSAPrivateKey.LoadFromStream(AStream: TStream; AFormat: TPrivateKeyFormat = kpDefault); 707 | var 708 | KeyBuffer :pBIO; 709 | cb : ppem_password_cb; 710 | pKey : PEVP_PKEY; 711 | begin 712 | cb := nil; 713 | if Assigned(FOnNeedPassphrase) then 714 | cb := @ReadKeyCallback; 715 | 716 | SetLength(FBuffer, AStream.Size); 717 | AStream.ReadBuffer(FBuffer[0], AStream.Size); 718 | KeyBuffer := BIO_new_mem_buf(FBuffer, Length(FBuffer)); 719 | if KeyBuffer = nil then 720 | RaiseOpenSSLError('RSA load stream error'); 721 | try 722 | 723 | case AFormat of 724 | kpDefault: begin 725 | 726 | pKey := PEM_read_bio_PrivateKey(KeyBuffer, nil, cb, nil); 727 | if not Assigned(pKey) then 728 | RaiseOpenSSLError('PUBKEY load public key error'); 729 | 730 | try 731 | FRSA := EVP_PKEY_get1_RSA(pKey); 732 | 733 | if not Assigned(FRSA) then 734 | RaiseOpenSSLError('RSA load public key error'); 735 | finally 736 | EVP_PKEY_free(pKey); 737 | end; 738 | end; 739 | kpRSAPrivateKey: begin 740 | FRSA := PEM_read_bio_RSAPrivateKey(KeyBuffer, nil, cb, nil); 741 | if not Assigned(FRSA) then 742 | RaiseOpenSSLError('RSA load private key error'); 743 | end; 744 | else 745 | raise EOpenSSLError.Create('Invalid format'); 746 | end; 747 | 748 | finally 749 | BIO_free(KeyBuffer); 750 | end; 751 | end; 752 | 753 | { TRSAKeyPairPrivateKey } 754 | 755 | constructor TRSAKeyPairPrivateKey.Create(KeyPair: TRSAKeyPair); 756 | begin 757 | inherited Create; 758 | FKeyPair := KeyPair; 759 | end; 760 | 761 | procedure TRSAKeyPairPrivateKey.FreeRSA; 762 | begin 763 | end; 764 | 765 | function TRSAKeyPairPrivateKey.GetRSA: PRSA; 766 | begin 767 | Result := FKeyPair.FRSA; 768 | end; 769 | 770 | { TRSAPublicKey } 771 | 772 | constructor TRSAPublicKey.Create; 773 | begin 774 | inherited; 775 | FRSA := nil; 776 | end; 777 | 778 | procedure TRSAPublicKey.FreeRSA; 779 | begin 780 | if FRSA <> nil then 781 | begin 782 | RSA_free(FRSA); 783 | FRSA := nil; 784 | end; 785 | end; 786 | 787 | function TRSAPublicKey.GetRSA: PRSA; 788 | begin 789 | if Assigned(FCerificate) then 790 | Result := FCerificate.GetPublicRSA 791 | else 792 | Result := FRSA; 793 | end; 794 | 795 | procedure TRSAPublicKey.LoadFromStream(AStream: TStream; 796 | AFormat: TPublicKeyFormat); 797 | var 798 | KeyBuffer :pBIO; 799 | pKey :PEVP_PKEY; 800 | begin 801 | SetLength(FBuffer, AStream.Size); 802 | AStream.ReadBuffer(FBuffer[0], AStream.Size); 803 | KeyBuffer := BIO_new_mem_buf(FBuffer, Length(FBuffer)); 804 | if KeyBuffer = nil then 805 | RaiseOpenSSLError('RSA load stream error'); 806 | try 807 | case AFormat of 808 | kfDefault: begin 809 | pKey := PEM_read_bio_PubKey(KeyBuffer, nil, nil, nil); 810 | if not Assigned(pKey) then 811 | RaiseOpenSSLError('PUBKEY load public key error'); 812 | 813 | try 814 | FRSA := EVP_PKEY_get1_RSA(pKey); 815 | 816 | if not Assigned(FRSA) then 817 | RaiseOpenSSLError('RSA load public key error'); 818 | finally 819 | EVP_PKEY_free(pKey); 820 | end; 821 | end; 822 | kfRSAPublicKey: begin 823 | FRSA := PEM_read_bio_RSAPublicKey(KeyBuffer, nil, nil, nil); 824 | if not Assigned(FRSA) then 825 | RaiseOpenSSLError('RSA load public key error'); 826 | end; 827 | else 828 | raise EOpenSSLError.Create('Invalid format'); 829 | end; 830 | finally 831 | BIO_free(KeyBuffer); 832 | end; 833 | end; 834 | 835 | { TRSAKeyPairPublicKey } 836 | 837 | constructor TRSAKeyPairPublicKey.Create(KeyPair: TRSAKeyPair); 838 | begin 839 | inherited Create; 840 | FKeyPair := KeyPair; 841 | end; 842 | 843 | procedure TRSAKeyPairPublicKey.FreeRSA; 844 | begin 845 | 846 | end; 847 | 848 | function TRSAKeyPairPublicKey.GetRSA: PRSA; 849 | begin 850 | Result := FKeyPair.FRSA; 851 | end; 852 | 853 | end. 854 | -------------------------------------------------------------------------------- /Source/OpenSSL.RandUtils.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2018 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit OpenSSL.RandUtils; 23 | 24 | // https://www.openssl.org/docs/man1.1.0/crypto/RAND_load_file.html 25 | // https://www.openssl.org/docs/man1.1.1/man3/RAND_poll.html 26 | // https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html 27 | 28 | interface 29 | 30 | uses 31 | System.SysUtils; 32 | 33 | type 34 | TRandUtil = class(TObject) 35 | public 36 | // Calling InitPool is not necessary, because the DRBG polls the entropy source automatically 37 | class procedure InitPool; 38 | // true if the CSPRNG has been seeded with enough data 39 | class function Initialized: Boolean; 40 | // reads a number of bytes from file filename and adds them to the PRNG 41 | // if max_bytes is -1, the complete file is read 42 | // returns the number of bytes read 43 | class function LoadSeedFromFile(const FileName: string; MaxBytes: Integer = -1): Integer; 44 | // writes a number of random bytes (currently 1024) to file filename 45 | // which can be used to initialize the PRNG by calling RAND_load_file() in a later session 46 | // returns the number of bytes written 47 | class function SaveSeedToFile(const FileName: string): Integer; 48 | // generates a default path for the random seed file 49 | class function GetDefaultSeedFileName: string; 50 | // Generate a random number 51 | class function GetRandomBytes(const Size: Integer): TBytes; 52 | // Generate a cryptographically secure random number 53 | class function GetPseudoRandomBytes(const Size: Integer): TBytes; 54 | end; 55 | 56 | implementation 57 | 58 | uses 59 | OpenSSL.libeay32, OpenSSL.Core; 60 | 61 | { TRandUtil } 62 | 63 | class function TRandUtil.GetDefaultSeedFileName: string; 64 | const 65 | MaxLen = 255; 66 | var 67 | Filename: AnsiString; 68 | FilenameP: PAnsiChar; 69 | begin 70 | SetLength(Filename, MaxLen); 71 | FilenameP := RAND_file_name(@Filename[1], MaxLen); 72 | if not Assigned(FilenameP) then 73 | RaiseOpenSSLError('RAND_file_name error'); 74 | Result := string(AnsiString(PAnsiChar(Filename))); 75 | end; 76 | 77 | class function TRandUtil.GetPseudoRandomBytes(const Size: Integer): TBytes; 78 | var 79 | ErrCode: Integer; 80 | begin 81 | SetLength(Result, Size); 82 | ErrCode := RAND_pseudo_bytes(@Result[0], Size); 83 | if ErrCode = -1 then 84 | RaiseOpenSSLError('RAND method not supported'); 85 | if ErrCode = 0 then 86 | RaiseOpenSSLError('RAND_pseudo_bytes error'); 87 | end; 88 | 89 | class function TRandUtil.GetRandomBytes(const Size: Integer): TBytes; 90 | var 91 | ErrCode: Integer; 92 | begin 93 | SetLength(Result, Size); 94 | ErrCode := RAND_bytes(@Result[0], Size); 95 | if ErrCode = -1 then 96 | RaiseOpenSSLError('RAND method not supported'); 97 | if ErrCode = 0 then 98 | RaiseOpenSSLError('RAND_bytes error'); 99 | end; 100 | 101 | class function TRandUtil.Initialized: Boolean; 102 | var 103 | ErrCode: Integer; 104 | begin 105 | ErrCode := RAND_status(); 106 | Result := ErrCode = 1; 107 | end; 108 | 109 | class procedure TRandUtil.InitPool; 110 | var 111 | ErrCode: Integer; 112 | begin 113 | ErrCode := RAND_poll(); 114 | if ErrCode <> 1 then 115 | RaiseOpenSSLError('RAND_poll error'); 116 | end; 117 | 118 | class function TRandUtil.LoadSeedFromFile(const FileName: string; 119 | MaxBytes: Integer): Integer; 120 | begin 121 | Result := RAND_load_file(@FileName[1], MaxBytes); 122 | if Result < 0 then 123 | RaiseOpenSSLError('RAND_load_file error'); 124 | end; 125 | 126 | class function TRandUtil.SaveSeedToFile(const FileName: string): Integer; 127 | begin 128 | Result := RAND_write_file(@FileName[1]); 129 | if Result < 0 then 130 | RaiseOpenSSLError('RAND_write_file error'); 131 | end; 132 | 133 | end. 134 | -------------------------------------------------------------------------------- /Source/OpenSSL.SMIMEUtils.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | 23 | // enc - symmetric cipher routines 24 | // https://www.openssl.org/docs/manmaster/apps/enc.html 25 | 26 | unit OpenSSL.SMIMEUtils; 27 | 28 | interface 29 | 30 | uses 31 | System.Classes, System.SysUtils, 32 | OpenSSL.libeay32, OpenSSL.Core, IdSSLOpenSSLHeaders; 33 | 34 | type 35 | TSMIMEUtil = class(TOpenSLLBase) 36 | public 37 | function Decrypt(InputStream, OutputStream :TStream; Verify, NoVerify: Boolean): Integer; 38 | end; 39 | 40 | implementation 41 | 42 | { TSMIMEUtil } 43 | 44 | function TSMIMEUtil.Decrypt(InputStream, OutputStream: TStream; Verify, NoVerify: Boolean): Integer; 45 | var 46 | LInput, LOutput, LContent: PBIO; 47 | LPKCS7: PPKCS7; 48 | LStore: PX509_STORE; 49 | LCerts: PSTACK_OF_X509; 50 | LFlags, LOutputLen: Integer; 51 | LOutputBuffer, LInputBuffer: TBytes; 52 | begin 53 | 54 | Result := 0; 55 | LFlags := 0; 56 | if NoVerify then 57 | LFlags := PKCS7_NOVERIFY; 58 | LContent := nil; 59 | LCerts := nil; 60 | LInput := nil; 61 | LOutput := nil; 62 | LStore := X509_STORE_new(); 63 | try 64 | SetLength(LInputBuffer, InputStream.Size); 65 | InputStream.ReadBuffer(LInputBuffer[0], InputStream.Size); 66 | 67 | LInput := BIO_new_mem_buf(LInputBuffer, InputStream.Size); 68 | if not Assigned(LInput) then 69 | RaiseOpenSSLError('BIO_new_file'); 70 | 71 | LPKCS7 := nil; 72 | LPKCS7 := d2i_PKCS7_bio(LInput, LPKCS7); 73 | 74 | if not Assigned(LPKCS7) then 75 | RaiseOpenSSLError('FSMIME_read_PKCS7'); 76 | 77 | LOutput := BIO_new(BIO_s_mem()); 78 | if not Assigned(LOutput) then 79 | RaiseOpenSSLError('BIO_new'); 80 | 81 | if Verify then 82 | begin 83 | Result := PKCS7_verify(LPKCS7, LCerts, LStore, LContent, LOutput, LFlags); 84 | 85 | if Assigned(LOutput) and Assigned(OutputStream) then 86 | begin 87 | LOutputLen := LOutput.num_write; 88 | SetLength(LOutputBuffer, LOutputLen); 89 | BIO_read(LOutput, LOutputBuffer, LOutputLen); 90 | 91 | OutputStream.WriteBuffer(LOutputBuffer, LOutputLen); 92 | end; 93 | end; 94 | finally 95 | BIO_free(LInput); 96 | BIO_free(LOutput); 97 | BIO_free(LContent); 98 | end; 99 | end; 100 | 101 | end. 102 | -------------------------------------------------------------------------------- /Source/OpenSSL.libeay32.pas: -------------------------------------------------------------------------------- 1 | {******************************************************************************} 2 | { } 3 | { Delphi OPENSSL Library } 4 | { Copyright (c) 2016 Luca Minuti } 5 | { https://bitbucket.org/lminuti/delphi-openssl } 6 | { } 7 | {******************************************************************************} 8 | { } 9 | { Licensed under the Apache License, Version 2.0 (the "License"); } 10 | { you may not use this file except in compliance with the License. } 11 | { You may obtain a copy of the License at } 12 | { } 13 | { http://www.apache.org/licenses/LICENSE-2.0 } 14 | { } 15 | { Unless required by applicable law or agreed to in writing, software } 16 | { distributed under the License is distributed on an "AS IS" BASIS, } 17 | { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. } 18 | { See the License for the specific language governing permissions and } 19 | { limitations under the License. } 20 | { } 21 | {******************************************************************************} 22 | unit OpenSSL.libeay32; 23 | 24 | interface 25 | 26 | uses 27 | System.Classes, System.SysUtils, IdSSLOpenSSLHeaders, IdSSLOpenSSL; 28 | 29 | const 30 | { S/MIME related flags } 31 | PKCS7_TEXT = $1; 32 | PKCS7_NOCERTS = $2; 33 | PKCS7_NOSIGS = $4; 34 | PKCS7_NOCHAIN = $8; 35 | PKCS7_NOINTERN = $10; 36 | PKCS7_NOVERIFY = $20; 37 | PKCS7_DETACHED = $40; 38 | PKCS7_BINARY = $80; 39 | PKCS7_NOATTR = $100; 40 | PKCS7_NOSMIMECAP = $200; 41 | PKCS7_NOOLDMIMETYPE = $400; 42 | PKCS7_CRLFEOL = $800; 43 | PKCS7_STREAM = $1000; 44 | PKCS7_NOCRL = $2000; 45 | PKCS7_PARTIAL = $4000; 46 | PKCS7_REUSE_DIGEST = $8000; 47 | PKCS7_NO_DUAL_CONTENT = $10000; 48 | 49 | { Flags: for compatibility with older code } 50 | SMIME_TEXT = PKCS7_TEXT; 51 | SMIME_NOCERTS = PKCS7_NOCERTS; 52 | SMIME_NOSIGS = PKCS7_NOSIGS; 53 | SMIME_NOCHAIN = PKCS7_NOCHAIN; 54 | SMIME_NOINTERN = PKCS7_NOINTERN; 55 | SMIME_NOVERIFY = PKCS7_NOVERIFY; 56 | SMIME_DETACHED = PKCS7_DETACHED; 57 | SMIME_BINARY = PKCS7_BINARY; 58 | SMIME_NOATTR = PKCS7_NOATTR; 59 | 60 | var 61 | X509_get_pubkey : function (a: pX509): pEVP_PKEY; cdecl; 62 | 63 | EVP_BytesToKey : function (cipher_type: PEVP_CIPHER; md: PEVP_MD; salt: PByte; data: PByte; datal: integer; count: integer; key: PByte; iv: PByte): integer; cdecl; 64 | EVP_DecryptUpdate : function (ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer; data_in: PByte; inl: integer): integer; cdecl; 65 | EVP_DecryptFinal : function (ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer): integer; cdecl; 66 | EVP_DecryptFinal_ex : function(ctx : PEVP_CIPHER_CTX; outm: PByte; var outl : integer) : integer cdecl = nil; 67 | 68 | BIO_free_all : procedure (a: pBIO); cdecl; 69 | BIO_push : function (b :pBIO; append :pBIO) :pBIO; cdecl; 70 | BIO_pop : function (b :pBIO) :pBIO; cdecl; 71 | BIO_set_next : function (b :pBIO; next :pBIO) :pBIO; cdecl; 72 | RSA_print : function (bp :pBIO; x: pRSA; offset: Integer): Integer; cdecl; 73 | 74 | // EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); 75 | // 76 | PEM_read_bio_PUBKEY : function(bp : PBIO; x : PPEVP_PKEY; cb : ppem_password_cb; u: Pointer) : PEVP_PKEY cdecl; 77 | PEM_write_bio_PUBKEY : function(bp : PBIO; x : PEVP_PKEY) : PEVP_PKEY cdecl; 78 | 79 | d2i_PKCS7_bio: function(bp: PBIO; var pkcs7: PPKCS7): PPKCS7; cdecl; 80 | PKCS7_verify: function(p7: PPKCS7; certs: PSTACK_OF_X509; store: PX509_STORE; indata, outdata: PBIO; flags: Integer): Integer cdecl; 81 | X509_STORE_new: function(): PX509_STORE; cdecl; 82 | 83 | RAND_bytes : function (buf: PAnsiChar; num: Integer): Integer cdecl; 84 | RAND_pseudo_bytes : function (buf: PAnsiChar; num: Integer): Integer cdecl; 85 | RAND_status: function: Integer cdecl; 86 | RAND_poll: function: Integer cdecl; 87 | RAND_file_name: function (buf: PAnsiChar; num: Integer): PAnsiChar cdecl; 88 | RAND_load_file: function (filename: PAnsiChar; max_bytes: Integer): Integer cdecl; 89 | RAND_write_file: function (filename: PAnsiChar): Integer; 90 | 91 | function BIO_get_mem_data(b : PBIO; pp : Pointer) : Integer; 92 | function BIO_to_string(b : PBIO; Encoding: TEncoding): string; overload; 93 | function BIO_to_string(b : PBIO): string; overload; 94 | 95 | function LoadOpenSSLLibraryEx :Boolean; 96 | procedure UnLoadOpenSSLLibraryEx; 97 | 98 | procedure OPENSSL_free(address: pointer); 99 | 100 | implementation 101 | 102 | uses 103 | Winapi.Windows; 104 | 105 | const 106 | LIBEAY_DLL_NAME = 'libeay32.dll'; 107 | 108 | var 109 | hSSL :HMODULE; 110 | 111 | 112 | //function X509_get_pubkey(a: pX509): pEVP_PKEY; cdecl; external LIBEAY_DLL_NAME; 113 | // 114 | //procedure BIO_free_all(a: pBIO); cdecl; external LIBEAY_DLL_NAME; 115 | 116 | function BIO_get_mem_data(b : PBIO; pp : Pointer) : Integer; 117 | begin 118 | Result := BIO_ctrl(b,BIO_CTRL_INFO,0,pp); 119 | end; 120 | 121 | function BIO_to_string(b : PBIO; Encoding: TEncoding): string; 122 | const 123 | BuffSize = 1024; 124 | var 125 | Buffer: TBytes; 126 | begin 127 | Result := ''; 128 | SetLength(Buffer, BuffSize); 129 | while BIO_read(b, buffer, BuffSize) > 0 do 130 | begin 131 | Result := Result + Encoding.GetString(Buffer); 132 | end; 133 | end; 134 | 135 | function BIO_to_string(b : PBIO): string; overload; 136 | begin 137 | Result := BIO_to_string(b, TEncoding.ANSI); 138 | end; 139 | 140 | procedure OPENSSL_free(address: pointer); 141 | begin 142 | CRYPTO_free(address); 143 | end; 144 | 145 | procedure ResetFuncPointers; 146 | begin 147 | hSSL := 0; 148 | X509_get_pubkey := nil; 149 | BIO_free_all := nil; 150 | PEM_read_bio_PUBKEY := nil; 151 | PEM_write_bio_PUBKEY := nil; 152 | EVP_BytesToKey := nil; 153 | EVP_DecryptUpdate := nil; 154 | EVP_DecryptFinal := nil; 155 | EVP_DecryptFinal_ex := nil; 156 | BIO_push := nil; 157 | BIO_pop := nil; 158 | BIO_set_next := nil; 159 | 160 | RSA_print := nil; 161 | 162 | d2i_PKCS7_bio := nil; 163 | PKCS7_verify := nil; 164 | X509_STORE_new := nil; 165 | RAND_bytes := nil; 166 | RAND_pseudo_bytes := nil; 167 | RAND_status := nil; 168 | RAND_poll := nil; 169 | RAND_file_name := nil; 170 | RAND_load_file := nil; 171 | RAND_write_file := nil; 172 | end; 173 | 174 | function LoadOpenSSLLibraryEx :Boolean; 175 | begin 176 | if hSSL <> 0 then 177 | Exit(True); 178 | 179 | Result := IdSSLOpenSSL.LoadOpenSSLLibrary; 180 | if Result then 181 | begin 182 | hSSL := LoadLibrary(LIBEAY_DLL_NAME); 183 | if hSSL = 0 then 184 | Exit(False); 185 | X509_get_pubkey := GetProcAddress(hSSL, 'X509_get_pubkey'); 186 | BIO_free_all := GetProcAddress(hSSL, 'BIO_free_all'); 187 | PEM_read_bio_PUBKEY := GetProcAddress(hSSL, 'PEM_read_bio_PUBKEY'); 188 | PEM_write_bio_PUBKEY := GetProcAddress(hSSL, 'PEM_write_bio_PUBKEY'); 189 | EVP_BytesToKey := GetProcAddress(hSSL, 'EVP_BytesToKey'); 190 | EVP_DecryptUpdate := GetProcAddress(hSSL, 'EVP_DecryptUpdate'); 191 | EVP_DecryptFinal := GetProcAddress(hSSL, 'EVP_DecryptFinal'); 192 | EVP_DecryptFinal_ex := GetProcAddress(hSSL, 'EVP_DecryptFinal_ex'); 193 | BIO_push := GetProcAddress(hSSL, 'BIO_push'); 194 | BIO_pop := GetProcAddress(hSSL, 'BIO_pop'); 195 | BIO_set_next := GetProcAddress(hSSL, 'BIO_set_next'); 196 | 197 | RSA_print := GetProcAddress(hSSL, 'RSA_print'); 198 | 199 | d2i_PKCS7_bio := GetProcAddress(hSSL, 'd2i_PKCS7_bio'); 200 | PKCS7_verify := GetProcAddress(hSSL, 'PKCS7_verify'); 201 | X509_STORE_new := GetProcAddress(hSSL, 'X509_STORE_new'); 202 | RAND_bytes := GetProcAddress(hSSL, 'RAND_bytes'); 203 | RAND_pseudo_bytes := GetProcAddress(hSSL, 'RAND_pseudo_bytes'); 204 | RAND_status := GetProcAddress(hSSL, 'RAND_status'); 205 | RAND_poll := GetProcAddress(hSSL, 'RAND_poll'); 206 | RAND_file_name := GetProcAddress(hSSL, 'RAND_file_name'); 207 | RAND_load_file := GetProcAddress(hSSL, 'RAND_load_file'); 208 | RAND_write_file := GetProcAddress(hSSL, 'RAND_write_file'); 209 | 210 | OpenSSL_add_all_algorithms; 211 | OpenSSL_add_all_ciphers; 212 | OpenSSL_add_all_digests; 213 | ERR_load_crypto_strings; 214 | end; 215 | end; 216 | 217 | procedure UnLoadOpenSSLLibraryEx; 218 | begin 219 | if hSSL <> 0 then 220 | begin 221 | FreeLibrary(hSSL); 222 | ResetFuncPointers; 223 | end; 224 | end; 225 | 226 | initialization 227 | ResetFuncPointers; 228 | //LoadOpenSSLLibrary; 229 | 230 | finalization 231 | UnLoadOpenSSLLibraryEx; 232 | 233 | end. 234 | -------------------------------------------------------------------------------- /TestData/TestPKCS7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lminuti/Delphi-OpenSSL/a0ac36958bd745c7a8871dfe4e1722a49356f96f/TestData/TestPKCS7.pdf -------------------------------------------------------------------------------- /TestData/create_cert.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | openssl req -x509 -nodes -newkey rsa:2048 -keyout privatekey.pem -out publiccert.pem -days 500 3 | openssl x509 -pubkey -noout -in publiccert.pem > publickey.pem -------------------------------------------------------------------------------- /TestData/create_cert_pwd.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | openssl req -x509 -newkey rsa:2048 -keyout privatekey-pwd.pem -out publiccert-pwd.pem -days 500 3 | openssl x509 -pubkey -noout -in publiccert-pwd.pem > publickey-pwd.pem -------------------------------------------------------------------------------- /TestData/create_p7m.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | openssl smime -sign -in TestPKCS7.pdf -binary -signer publiccert.pem -inkey privatekey.pem -out TestPKCS7.pdf.p7m -outform DER -nodetach --------------------------------------------------------------------------------