├── .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
--------------------------------------------------------------------------------