aboutsummaryrefslogtreecommitdiffstats
path: root/src/_openssl
blob: 94b734ef843c2b1048ce2369c46be929ff56c651 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
#compdef openssl
# ------------------------------------------------------------------------------
# Copyright (c) 2011 Github zsh-users - https://github.com/zsh-users
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the zsh-users nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
# Description
# -----------
#
#  Completion script for OpenSSL 3.5.3 (https://www.openssl-library.org/)
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Aaron Schrab <aaron@schrab.com>
#  * Dimitris Apostolou <dimitris.apostolou@icloud.com>
#  * Shohei Yoshida <https://github.com/syohex/>
#
# ------------------------------------------------------------------------------

_openssl() {
  typeset -A opt_args
  local context state line
  local curcontext="$curcontext"
  local ret=1

  local -a openssl_tls_flags=(
    '-ssl3[enable SSL3 protocol]'
    '-no_ssl3[disable SSL3 protocol]'
    '-tls1[enable TLS1 protocol]'
    '-no_tls1[disable TLS1 protocol]'
    '-tls1_1[enable TLS1.1 protocol]'
    '-no_tls1_1[disable TLS1.1 protocol]'
    '-tls1_2[enable TLS1.2 protocol]'
    '-no_tls1_2[disable TLS1.2 protocol]'
    '-tls1_3[enable TLS1.3 protocol]'
    '-no_tls1_3[disable TLS1.3 protocol]'
  )

  local -a openssl_dtls_flags=(
    '-dtls[use DTLS instead of TLS]'
    '-dtls1[use DTLS1 instead of TLS]'
    '-dtls2[use DTLS2 instead of TLS]'
  )

  local -a openssl_extended_verification_flags=(
    '-xkey[extra private key file]:file:_files'
    '-xcert[extra certificate file]:file:_files'
    '-xchain[extra certificate chain file]:file:_files'
    '-xchain_build[build the certificate chain for the extra certificates]'
    '-xcertform[extra certificate format]:format[DER PEM P12]'
  )

  local -a openssl_supported_commands_flags=(
    '-bugs[set various bug workarounds]'
    '(-comp -no_comp)-no_comp[disable support for SSL/TLS compression]'
    '(-comp -no_comp)-comp[enable support for SSL/TLS compression]'
    '-no_ticket[disable support for session tickets]'
    '-serverpref[use server and not client preference order when determining cipher suite]'
    '-client_renegotiation[allow servers to accept client-initiated renegotiation]'
    '-legacy_renegotiation[permit the use of unsafe legacy renegotiation]'
    '-no_renegotiation[disable all attempts at renegotiation in (D)TLSv1.2 and earlier]'
    '-no_resumption_on_reneg[set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION]'
    '(-legacy_server_connect -no_legacy_server_connect)-legacy_server_connect[permit unsafe legacy renegotiation]'
    '(-legacy_server_connect -no_legacy_server_connect)-no_legacy_server_connect[prohibit unsafe legacy renegotiation]'
    '-prioritize_chacha[prioritize ChaCha ciphers when the client has a ChaCha20 cipher]'
    '-allow_no_dhe_kex[allow a non-(ec)dhe based key exchange mode on resumption]'
    '-strict[enable strict mode protocol handling]'
    '-sigalgs[set signature algorithms for TLSv1.2 and TLSv1.3]:alg:_openssl_signature_algorithms'
    '-client_sigalgs[set signature algorithms for client authentication for TLSv1.2 and TLSv1.3]:alg:_openssl_signature_algorithms'
    '-groups[set the supported groups(colon separated NIST name or OpenSSL OID name)]:groups:_openssl_groups'
    '-curves[set the curves groups]:groups:_openssl_groups'
    '-named_curve[set the temporary curve for ephemeral ECDH modes]:curve'
    '-cipher[set the TLSv1.2 and below ciphersuite list to ciphers]:ciphers'
    '-ciphersuites[set the available ciphersuites for TLSv1.3]:ciphers'
    '-min_protocol[minimum supported protocol]:protocol:_openssl_tls_protocols'
    '-max_protocol[maximum supported protocol]:protocol:_openssl_tls_protocols'
    '-record_padding[padding length for TLSv1.3 records]:padding'
    '-no_middlebox[turn of middlebox compatibility]'
  )

  local -a openssl_provider_options=(
    '-provider[provider ID to be loaded and initialized]:provider'
    '-provider-path[search path that is to be used for looking for providers]:path:_files -/'
    '*-provparam[configuration parameter key to value val in provider name]:key_value'
    '-propquery[property query clause to be used when fetching algorithms from the loaded providers]:query'
  )

  local -a openssl_trusted_certificate_options=(
    '-CAfile[load the specified file which contains a certificate or several of them]:file:_files'
    '-no-CAfile[do not load the default file of trusted certificates]'
    '-CApath[directory as a collection of trusted certificates]:dir:_files -/'
    '-no-CApath[do not use the default directory of trusted certificates]'
    '-CAstore[URI as a store of CA certificates]:uri'
    '-no-CAstore[do not use the default store of trusted CA certificates]'
  )

  local -a openssl_random_state_options=(
    '-rand[file containing random data used to seed the random number generator]:file:_files'
    '-writerand[file to be written the seed data]:file:_files'
  )

  local -a openssl_verification_options=(
    '-allow_proxy_certs[allow the verification of proxy certificates]'
    '-attime[perform validation checks using time specified by timestamp and not current system time]:time'
    '-no_check_time[suppresses checking the validity period of certificates and CRLs against the current time]'
    '-check_ss_sig[verify the signature of the last certificate in a chain if the certificate is supposedly self-signed]'
    '-crl_check[checks end entity certificate validity by attempting to look up a valid CRL]'
    '-crl_check_all[checks the validity of all certificates in the chain by attempting to look up valid CRL]'
    '-explicit_policy[set policy variable require-explicit-policy]'
    '-extended_crl[enable extended CRL features]'
    '-ignore_critical[ignore critical extensions]'
    '-inhibit_any[set policy variable inhibit-any-policy]'
    '-inhibit_map[set policy variable inhibit-policy-mapping]'
    '-partial_chain[allow verification to succeed if an incomplete chain can be built]'
    '-policy[enable policy processing and add arg to the user-initial-policy-set]:policy'
    '-policy_check[enables certificate policy processing]'
    '-policy_print[print out diagnostics related to policy processing]'
    '-purpose[a high-level specification of the intended use of the target certificate]:purpose'
    '-suiteB_128[enable the Suite B mode operation at 128 bit Level of Security]'
    '-suiteB_128_only[enable only the Suite B mode operation at 128 bit Level of Security]'
    '-suiteB_192[enable the Suite B mode operation at 192 bit Level of Security]'
    '-use_deltas[enable support for delta CRLs]'
    '-auth_level[set the certificate chain authentication security level]:level'
    '-verify_depth[limit the certificate chain to num intermediate CA certificates]:depth'
    '-verify_email[verify the email address in Subject Alternative Name or the email]:email'
    '-verify_hostname[verify hostname in Subject Alternative Name or Common Name]:hostname'
    '-verify_ip[verify IP addresses in Subject Alternative Name of the subject certificate]:ip'
    '-x509_strict[disables non-compliant workarounds for broken certificates]'
  )

  _arguments -C -A "-*" \
    '(- *)-help[show help]' \
    '(- *)-version[show version]' \
    '1: :_openssl_subcommands' \
    '*::arg:->args' \
    && ret=0

  case "$state" in
    (args)
      local subcmd=${words[1]}
      if (( $+functions[_openssl_${subcmd}] )); then
        _openssl_${subcmd} && ret=0
      else
        local -a cipher_flags=($(openssl enc -list | tail -n +2 ))
        local -a ciphers=()
        for flag in $cipher_flags[@]
        do
          ciphers+=(${flag:1})
        done

        if (( $ciphers[(I)$subcmd] )); then
          _openssl_enc 1 && ret=0
        else
          local -a digest_flags=($(openssl dgst -list | tail -n +2 ))
          local -a digests=()
          for flag in $digest_flags[@]
          do
            digests+=(${flag:1})
          done

          if (( $digests[(I)$subcmd] )); then
            _openssl_dgst 1 && ret=0
          fi
        fi
      fi

      ;;
  esac

  return ret
}

_openssl_subcommands() {
  local -a commands=(
    'asn1parse:Parse an ASN.1 sequence'
    'ca:Certificate Authority Management'
    'ciphers:Cipher Suite Description Determination'
    'cmp:Certificate Management Protocol(CMP) application'
    'cms:Cryptographic Message Syntax command'
    'crl:Certificate Revocation List Management'
    'crl2pkcs7:CRL to PKCS#7 Conversion'
    'dgst:Message Digest calculation'
    'dhparam: Generation and Management of Diffie-Hellman Parameters'
    'dsa: DSA Data Management'
    'dsaparam:DSA Parameter Generation and Management'
    'ec:Elliptic curve key processing'
    'ecparam:EC parameter manipulation and generation'
    'enc:Encryption, decryption, and encoding'
    'engine:Engine (loadable module) information and manipulation'
    'errstr:Error Number to Error String Conversion'
    'fipsinstall:FIPS configuration installation'
    'gendsa:Generation of DSA Private Key from Parameters'
    'genpkey:Generation of Private Key or Parameters'
    'genrsa:Generation of RSA Private Key'
    "help:Display information about a command's options"
    'info:Display diverse information built into the OpenSSL libraries'
    'list:List algorithms and features'
    'mac:Message Authentication Code Calculation'
    'nseq:Create or examine a Netscape certificate sequence'
    'ocsp:Online Certificate Status Protocol command'
    'passwd:Generation of hashed passwords'
    'pkcs12:PKCS#12 Data Management'
    'pkcs7:PKCS#7 Data Management'
    'pkcs8:PKCS#8 format private key conversion command'
    'pkey:Public and private key management'
    'pkeyparam:Public key algorithm parameter management'
    'pkeyutl:Public key algorithm cryptographic operation command'
    'prime:Compute prime numbers'
    'rand:Generate pseudo-random bytes'
    'rehash:Create symbolic links to certificate and CRL files named by the hash values'
    'req:PKCS#10 X.509 Certificate Signing Request Management'
    'rsautl:RSA command for signing, verification, encryption, and decryption'
    's_client:SSL/TLS client program'
    's_server:SSL/TLS server program'
    's_time:SSL Connection Timer'
    'sess_id:SSL Session Data Management'
    'smime:S/MIME mail processing'
    'speed:Algorithm Speed Measurement'
    'spkac:SPKAC printing and generating command'
    'srp:Maintain SRP password file(deprecated)'
    'storeutl:Command to list and display certificates, keys, CRLs, etc'
    'ts:Time Stamping Authority command'
    'verify:X.509 Certificate Verification'
    'version:OpenSSL Version Information'
    'x509:X.509 Certificate Data Management'

    # Message Digest Commands
    'blake2b512:BLAKE2b-512 Digest'
    'blake2s256:BLAKE2s-256 Digest'
    'md2:MD2 Digest'
    'md4:MD4 Digest'
    'md5:MD5 Digest'
    'mdc2:MDC2 Digest'
    'rmd160:RMD-160 Digest'
    'sha1:SHA-1 Digest'
    'sha224:SHA-2 224 Digest'
    'sha256:SHA-2 256 Digest'
    'sha384:SHA-2 384 Digest'
    'sha512:SHA-2 512 Digest'
    'sha3-224:SHA-3 224 Digest'
    'sha3-256:SHA-3 256 Digest'
    'sha3-384:SHA-3 384 Digest'
    'sha3-512:SHA-3 512 Digest'
    'keccak-224:KECCAK 224 Digest'
    'keccak-256:KECCAK 256 Digest'
    'keccak-384:KECCAK 384 Digest'
    'keccak-512:KECCAK 512 Digest'
    'shake128:SHA-3 SHAKE128 Digest'
    'shake256:SHA-3 SHAKE256 Digest'
    'sm3:SM3 Digest'

    # Encryption, Decryption, and Encoding Commands
    'aes128:AES-128 Cipher'
    'aes-128-cbc:AES-128 CBC Cipher'
    'aes-128-cfb:AES-128 CFB Cipher'
    'aes-128-ctr:AES-128 CTR Cipher'
    'aes-128-ecb:AES-128 ECB Cipher'
    'aes-128-ofb:AES-128 OFB Cipher'
    'aes192:AES-192 Cipher'
    'aes-192-cbc:AES-192 CBC Cipher'
    'aes-192-cfb:AES-192 CFB Cipher'
    'aes-192-ctr:AES-192 CTR Cipher'
    'aes-192-ecb:AES-192 ECB Cipher'
    'aes-192-ofb:AES-192 OFB Cipher'
    'aes256:AES-256 Cipher'
    'aes-256-cbc:AES-256 CBC Cipher'
    'aes-256-cfb:AES-256 CFB Cipher'
    'aes-256-ctr:AES-256 CTR Cipher'
    'aes-256-ecb:AES-256 ECB Cipher'
    'aes-256-ofb:AES-256 OFB Cipher'

    'aria128:Aria-128 Cipher'
    'aria-128-cbc:Aria-128 CBC Cipher'
    'aria-128-cfb:Aria-128 CFB Cipher'
    'aria-128-ctr:Aria-128 CTR Cipher'
    'aria-128-ecb:Aria-128 ECB Cipher'
    'aria-128-ofb:Aria-128 OFB Cipher'
    'aria192:Aria-192 Cipher'
    'aria-192-cbc:Aria-192 CBC Cipher'
    'aria-192-cfb:Aria-192 CFB Cipher'
    'aria-192-ctr:Aria-192 CTR Cipher'
    'aria-192-ecb:Aria-192 ECB Cipher'
    'aria-192-ofb:Aria-192 OFB Cipher'
    'aria256:Aria-256 Cipher'
    'aria-256-cbc:Aria-256 CBC Cipher'
    'aria-256-cfb:Aria-256 CFB Cipher'
    'aria-256-ctr:Aria-256 CTR Cipher'
    'aria-256-ecb:Aria-256 ECB Cipher'
    'aria-256-ofb:Aria-256 OFB Cipher'

    'base64:Base64 Encoding'

    'bf:Blowfish Cipher'
    'bf-cbc:Blowfish CBC Cipher'
    'bf-cfb:Blowfish CFB Cipher'
    'bf-ecb:Blowfish ECB Cipher'
    'bf-ofb:Blowfish OFB Cipher'

    'camellia128:Camellia-128 Cipher'
    'camellia-128-cbc:Camellia-128 CBC Cipher'
    'camellia-128-cfb:Camellia-128 CFB Cipher'
    'camellia-128-ctr:Camellia-128 CTR Cipher'
    'camellia-128-ecb:Camellia-128 ECB Cipher'
    'camellia-128-ofb:Camellia-128 OFB Cipher'
    'camellia192:Camellia-192 Cipher'
    'camellia-192-cbc:Camellia-192 CBC Cipher'
    'camellia-192-cfb:Camellia-192 CFB Cipher'
    'camellia-192-ctr:Camellia-192 CTR Cipher'
    'camellia-192-ecb:Camellia-192 ECB Cipher'
    'camellia-192-ofb:Camellia-192 OFB Cipher'
    'camellia256:Camellia-256 Cipher'
    'camellia-256-cbc:Camellia-256 CBC Cipher'
    'camellia-256-cfb:Camellia-256 CFB Cipher'
    'camellia-256-ctr:Camellia-256 CTR Cipher'
    'camellia-256-ecb:Camellia-256 ECB Cipher'
    'camellia-256-ofb:Camellia-256 OFB Cipher'

    'cast:CAST Cipher'
    'cast-cbc:CAST CBC Cipher'

    'cast5-cbc:CAST5 CBC Cipher'
    'cast5-cfb:CAST5 CFB Cipher'
    'cast5-ecb:CAST5 ECB Cipher'
    'cast5-ofb:CAST5 OFB Cipher'

    'chacha20:Chacha20 Cipher'

    'des:DES Ciper'
    'des-cbc:DES CBC Ciper'
    'des-cfb:DES CFB Ciper'
    'des-ecb:DES ECB Ciper'
    'des-ede:DES EDE Ciper'
    'des-ede-cbc:DES EDE CBC Ciper'
    'des-ede-cfb:DES EDE CFB Ciper'
    'des-ede-ofb:DES EDE OFB Ciper'
    'des-ofb:DES OFB Ciper'

    'des3:Triple-DES Ciper'
    'desx:Triple-DES X Ciper'
    'des-ede3:Triple-DES EDE Ciper'
    'des-ede3-cbc:Triple-DES EDE CBC Ciper'
    'des-ede3-cfb:Triple-DES EDE CFB Ciper'
    'des-ede3-ofb:Triple-DES EDE OFB Ciper'

    'idea:IDEA Ciper'
    'idea-cbc:IDEA CBC Ciper'
    'idea-cfb:IDEA CFB Ciper'
    'idea-ecb:IDEA ECB Ciper'
    'idea-ofb:IDEA OFB Ciper'

    'rc2:RC2 Ciper'
    'rc2-cbc:RC2 CBC Ciper'
    'rc2-cfb:RC2 CFB Ciper'
    'rc2-ecb:RC2 ECB Ciper'
    'rc2-ofb:RC2 OFB Ciper'

    'rc4:RC4 Ciper'

    'rc5:RC5 Ciper'
    'rc5-cbc:RC5 CBC Ciper'
    'rc5-cfb:RC5 CFB Ciper'
    'rc5-ecb:RC5 ECB Ciper'
    'rc5-ofb:RC5 OFB Ciper'

    'seed:SEED Ciper'
    'seed-cbc:SEED CBC Ciper'
    'seed-cfb:SEED CFB Ciper'
    'seed-ecb:SEED ECB Ciper'
    'seed-ofb:SEED OFB Ciper'

    'sm4:SM4 Ciper'
    'sm4-cbc:SM4 CBC Ciper'
    'sm4-cfb:SM4 CFB Ciper'
    'sm4-ctr:SM4 CTR Ciper'
    'sm4-ecb:SM4 ECB Ciper'
    'sm4-ofb:SM4 OFB Ciper'
  )

  _describe -t commands 'command' commands "$@"
}

#
# Commands
#

_openssl_asn1parse() {
  _arguments \
    '(- *)-help[display this summary]' \
    '-inform[input format]:format:(DER PEM B64)' \
    '-in[input file]:file:_files' \
    '-out[output file(output format is always DER)]:file:_files' \
    '-noout[do not produce any output]' \
    '-offset[offset into file]:number' \
    '-length[length of section in file]:number' \
    '-i[indents the output]' \
    '-oid[file of extra oid definitions]:file:_files' \
    '-dump[unknown data in hex form]' \
    '-dlimit[dump the first arg bytes of unknown data in hex form]:bytes' \
    '-strparse[a series of these can be used to "dig"]:offset' \
    '-genstr[string to generate ASN1 structure from]:val' \
    '-genconf[file to generate ASN1 structure from]:file:_files' \
    '-strictpem[strict PEM]' \
    '-item[item to parse and print]:val'
}

_openssl_ca() {
  _arguments \
    '(- *)-help[print out a usage message]' \
    '-verbose[prints extra details about the operations being performed]' \
    '-quiet[prints fewer details about the operations being performed]' \
    '-config[specifies the configuration file to use]:file:_files' \
    '(-name -section)'{-name,-section}'[specifies the configuration file section to use]:section' \
    '-in[input filename containing a single certificate request to be signed by the CA]:file:_files' \
    '-inform[format to use when loading certificate request (CSR) input files]:type:(DER PEM)' \
    '-ss_cert[single self-signed certificate to be signed by the CA]:file:_files' \
    '-spkac[file containing a single Netscape signed public key and challenge to be signed by the CA]:file:_files' \
    '-infiles[all subsequent arguments are taken as the names  f files containing certificate requests]' \
    '-out[output file to output certificates to]:file:_files' \
    '-outdir[directory to output certificates to]:dir:_files -/' \
    '-cert[CA certificate]:file:_files' \
    '-certform[format of the data in certificate input files]:format:(DER PEM P12)' \
    '-keyfile[CA private key to sign certificate requests with]:file_or_uri:_files' \
    '-keyform[format of the private key input file]:format:(DER PEM P12 ENGINE)' \
    '-sigopt[pass options to the signature algorithm during sign operations]:option' \
    '-vfyopt[pass options to the signature algorithm during verify operations]:option' \
    '-key[The password used to encrypt the private key]:password' \
    '-passin[key password source for key files and certificate PKCS#12 files]:arg' \
    '-selfsign[certificates are to be signed with the key given with -keyfile]' \
    '-notext[do not output the text form of a certificate to the output file]' \
    '-dateopt[specify the date output format]:format:(rfc_822 iso_8601)' \
    '(-startdate -not_before)'{-startdate,-not_before}'[start date to be explicitly set]:date' \
    '(-enddate -not_after)'{-enddate,-not_after}'[expiry date to be explicitly set]:date' \
    '-days[number of days from today to certify the certificate for]:days' \
    '-md[message digest to use]:algorithm:(sha256 sha1 md5)' \
    '-policy[CA policy to use]:policy' \
    '-preserveDN[preserve DN order of a certificate]' \
    '-noemailDN[remove EMAIL field from the certificate]' \
    '-batch[enable batch mode]' \
    '-extensions[section of the configuration file to be added when certificate is issued]:section' \
    '-extfile[additional configuration file to read certificate extensions from]:file:_files' \
    '-subj[supersedes subject name given in the request]:subject' \
    '-utf8[field values to be interpreted as UTF8 string]' \
    '-create_serial[creates a new random serial to be used as next serial number]' \
    '-rand_serial[generate a large random number to use as the serial number]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-gencrl[generates a CRL based on information in the index file]' \
    "-crl_lastupdate[allows the value of the CRL's lastUpdate field to be explicitly set]:time" \
    "-crl_nextupdate[allows the value of the CRL's nextUpdate field to be explicitly set]:time" \
    '-crldays[number of days  before the next CRL is due]:days' \
    '-crlhours[number of hours before the next CRL is due]:hours' \
    '-crlsec[number of seconds before the next CRL is due]:seconds' \
    '-revoke[filename containing a certificate to revoke]:file:_files' \
    '-valid[filename containing a certificate to add a Valid certificate entry]:file:_files' \
    '-status[displays the revocation status of the certificate with the specified serial number]:serial' \
    '-updatedb[updates the database index to purge expired certificates]' \
    '-crl_reason[revocation reason]:reason:(unspecified keyCompromise CACompromise affiliationChanged superseded cessationOfOperation certificateHold removeFromCRL)' \
    '-crl_hold[sets the CRL revocation reason code to certificateHold and the hold instruction]:insn:(holdInstructionCallIssuer holdInstructionReject)' \
    '-crl_compromise[sets the revocation reason to keyCompromise and the compromise time]:time' \
    '-crl_CA_compromise[same as crl_compromise except the revocation reason is set to CACompromise]:time' \
    '-crlexts[section of the configuration file containing CRL extensions to include]:section' \
    '*:: :_files'
}

_openssl_ciphers() {
  _arguments \
    '(- *)-help[print help message]' \
    $openssl_provider_options[@] \
    '-s[only list supported ciphers]' \
    '-psk[include cipher suites which require PSK]' \
    '-srp[include cipher suites which require SRP]'\
    '-v[verbose output]' \
    '-V[like -v but include the official cipher suites values in hex]' \
    '-ssl3[list ciphers which could be used in SSL3 protocol negotiation]' \
    '-tls1[list ciphers which could be used in TLS1 protocol negotiation]' \
    '-tls1_1[list ciphers which could be used in TLS1.1 protocol negotiation]' \
    '-tls1_2[list ciphers which could be used in TLS1.2 protocol negotiation]' \
    '-tls1_3[list ciphers which could be used in TLS1.3 protocol negotiation]' \
    '-stdname[precede each cipher suite by its standard name]' \
    '-convert[connvert a standard cipher name to its OpenSSL name]:name' \
    '-ciphersuites[sets the list of TLSv1.3 ciphersuites]:suites' \
    '*:cipher_suite:_openssl_list_ciphers'
}

_openssl_cmp() {
  local -a info_types=(signKeyPairTypes caCerts rootCaCert certReqTemplate crlStatusList)
  local -a mac_algorithms=(
    hmacWithMD5 hmacWithRMD160 hmacWithSHA1 hmacWithSHA224 hmacWithSHA256 hmacWithSHA384
    hmacWithSHA512 hmac-sha1
  )

  _arguments \
    '(- *)-help[print help message]' \
    '-config[configuration file]:file:_files' \
    '-section[sections names to use within config file defining CMP options]:names' \
    '-verbosity[level of verbosity]:level:_openssl_cmp_verbosity_level' \
    '-cmd[CMP command to execute]:command:_openssl_cmp_commands' \
    '-infotype[InfoType name to use for requesting specific info in gem]:type:(($info_types))' \
    '-profile[name of a certificate profile in the PKIHeader generalInfo field]:name' \
    '-geninfo[a comma-separated list of InfoTypeAndValue]:values' \
    '-template[file to save any CRMF certTemplate in DER format]:file:_files' \
    '-keyspec[file to save any keySpec]:file:_files' \
    '-newkey[private or public key file or URI to be requested]:file_or_uri:_files' \
    '-newkeypass[pass phrase source for the key given with -newkey option]:source:_openssl_pass_phrase_options' \
    '-centralkeygen[request central key generation for certificate enrollment]' \
    '-newkeyout[file to save centrally generated private key in PEM format]:file:_files' \
    '-subject[X.509 Distinguished Name(DN) to use as subject field in requested certificate]:name' \
    '-days[number of days new certificate is requested to be valid for]:days' \
    '-reqexts[name of section in OpenSSL config file defining certificate request extensions]:name' \
    '-sans[addresses, email addresses, DNS names, URIS to add as SAN certificate request extension]:spec' \
    '-san_nodefault[disable to be copied from the reference certificate]' \
    '-policies[name of section to be set as certificate request extension]:name' \
    '-policy_oids[one or more OIDs to add as certificate policies request extension]:names' \
    '-policy_oids_critical[set policies given with -policy_oids as critical]' \
    '-popo[Proof-of-possession(POPO) method to use for IR/CR/KUR]:number:(0 1 2)' \
    '-csr[PKCS#10 CSR containing a certificate request]:file:_files' \
    '-out_trusted[trusted certificate file or URI to use for validating newly enrolled certificate]:file_or_uri:_files' \
    '-implicit_confirm[request implicit confirmation of newly enrolled certificates]' \
    '-disable_confirm[do not send certificate confirmation message for newly enrolled certificate]' \
    '-certout[file where any newly enrolled certificate should be saved]:file:_files' \
    '-chainout[file where the chain of any newly enrolled certificate should be saved]:file:_files' \
    '-oldcert[certificate file or URI to be updated message or to be revoked in RR messages]:file_or_uri:_files' \
    '-issuer[X.509 Distinguished Name(ND) to place as the issuer field]:name' \
    '-serial[serial number of certificate to be revoked in revocation request]:number' \
    '-revreason[CRLReason number to be included in revocation request]:reason:_openssl_cmp_revocation_reasons' \
    '-server[domain name or IP address and optionally port of CMP server to connect]:domain_or_ip' \
    '-proxy[proxy server to use for reaching CMP server]:domain_or_ip' \
    '-no_proxy[list of IP addresses and/or DNS names not to use proxy for]:addresses' \
    '-recipient[Distinguished Name(DN) to use in recipient field of CMP request message headers]:name' \
    '-path[HTTP path at CMP server to use for POST requests]:path' \
    '-keep_alive[keep alive type]:value:(0 1 2)' \
    '-msg_timeout[seconds a CMP request-response message round trip is allowed to take]:seconds' \
    '-total_timeout[maximum total seconds a transaction may take]:seconds' \
    '-trusted[certificate files or uris to use as trust anchors]:file_or_uri:_files' \
    '-untrusted[non-trusted intermediate CA certificate files or URIs]:file_or_uri:_files' \
    '-srvcert[CMP server certificate file or URI to expect and directly trust]:file_or_uri:_files' \
    '-expect_sender[Distinguished Name(DN) expected in the sender field of incoming CMP messages]:name' \
    '-ignore_keyusage[ignore key usage restrictions in CMP signer certificates]' \
    '-unprotected_errors[accept missing or invalid protection of negative responses from server]' \
    '-no_cache_extracerts[do not cache certificates in extraCerts field of CMP messages received]' \
    '-srvcert[file where to save successfully validated certificate]:file:_files' \
    '-extracertsout[file where to save the list of certificates contained in extraCert field]:file:_files' \
    '-cacertsout[file where to save the list of CA certificates contained in caPubs field]:file:_files' \
    '-oldwithold[root CA certificate to include in a genm request of infoType "rootCaCert"]:file:_files' \
    '-newwithnew[file to save newWithNew certificate received in a genp message]:file:_files' \
    '-newwithold[file to save any newWithOld certificate received in a genp message]:file:_files' \
    '-oldwithold[file to save any oldWithNew certificate received in a genp message]:file:_files' \
    '-crlcert[certificate to derive CRL issuer data for the source field]:file:_files' \
    '-oldcrl[CRL to obtain an update for in a genm request with infoType "crlStatusList"]:file:_files' \
    '-crlout[file to save any CRL received in a genp message of infoType "crls"]:file:_files' \
    '-ref[reference number/string/value to use as fallback senderKID]:value' \
    '-secret[source of a secret value to use with MAC-based message protection]:source:_openssl_pass_phrase_options' \
    "-cert[client's current CMP signer certificate file or URI]:file_or_uri:_files" \
    '-own_trusted[list of certificates to be used as trusted anchors]:file_or_uri:_files' \
    "-key[private key file or URI for the client's current certificate]:file_or_uri:_files" \
    '-keypass[pass pharse source for the private key]:source:_openssl_pass_phrase_options' \
    '-digest[digest to use in MSG_SIG_ALG and as the on-way function(OWF) in MSG_MAC_ALG]:digest:_openssl_digests' \
    '-mac[MAC algorithm in MSG_MAC_ALG]:alg:(($mac_algorithms))' \
    '-extracerts[certificates files or URIs to append in extraCerts field]:file_or_uri:_files' \
    '-unprotected_errors[send request messages without CMP-level protection]' \
    '-certform[file format to use when saving a certificate]:format:(PEM DER)' \
    '-crlform[file format to use when saving a CRL]:format(PEM DER)' \
    '-keyform[format of the key input]:format:(PEM DER P12 ENGINE)' \
    '-otherpass[pass phrase source for certificate]:source:_openssl_pass_phrase_options' \
    $openssl_provider_options[@] \
    $openssl_random_state_options[@] \
    '-tls_used[make the CMP client use TLS for message exchange]' \
    "-tls_cert[client's TLS certificate file or URI for authenticating to TLS server]:file_or_uri:_files" \
    "-tls_key[private key for client's TLS certificate]:file_or_uri:_files" \
    "-tls_keypass[pass phrase source for client's private TLS key]:source:_openssl_pass_phrase_options" \
    '-tls_extra[extra certificates file or URI to provite to TLS server during handshake]:file_or_uri:_files' \
    '-tls_trusted[trusted certificates to use for validating TLS server certificate]:file_or_uri:_files' \
    '-tls_host[address to be checked during hostname validation]:name' \
    '-batch[do not interactively prompt for input]' \
    '-repeat[number of times to invoke the command with the same parameters]:number' \
    '-reqin[files to take the sequence of CMP requests to send to server]:files:_files' \
    '-reqin_new_tid[use a fresh transaction ID for CMP request messages]' \
    '-reqout[file to save the sequence of CMP requests]:file:_files' \
    '-reqout_only[file to save the first CMP requests created by client]:file:_files' \
    '-rspin[files to save sequence of CMP responses]:file:_files' \
    '-rspout[file to save sequence of actually used CMP responses]:files:_files' \
    '-use_mock_srv[test the client using the internal CMP server mock-up at API level]' \
    '-port[port number of CMP mock-up server]:number' \
    '-max_msgs[maximum number of CMP messages that mock-up server should handle]:number' \
    '-srv_ref[reference value to use as snderKID of server]:value' \
    '-srv_secret[password source for server authentication with a pre-shared key]:arg' \
    '-srv_cert[certificate file or URI of the server]:file_or_uri:_files' \
    '-srv_cert[private key file or URI by the server for signing messages]:file_or_uri:_files' \
    '-srv_keypass[server private key file pass phrase source]:arg' \
    '-srv_trusted[trusted certificates for client authentication]:file_or_uri:_files' \
    '-srv_untrusted[untrusted intermediate CA certs files or URIs]:file_or_uri:_files' \
    '-ref_cert[certificate file or URI to be expected for RR messages]:file_or_uri:_files' \
    '-rsp_cert[certificate file or URI to be returned as mock enrollment result]:file_or_uri:_files' \
    '-rsp_key[private key to be returned as central key generation result]:file_or_uri:_files' \
    '-rsp_keypass[pass phrase source for rsp_cert and rsp_key]:arg' \
    '-rsp_crl[CRL file or URI to be returned in genp of type "crls"]:file_or_uri:_files' \
    '-rsp_extracerts[extra certificates to be include in mock certification responses]:file_or_uri:_files' \
    '-rsp_capubs[CA certificates to be included in mock Initialization Response message]:file_or_uri:_files' \
    '-rsp_newwithnew[certificate to be returned in newWithNew field of genp]:file_or_uri:_files' \
    '-rsp_newwithold[certificate to be returned in newWithPld field of genp]:file_or_uri:_files' \
    '-rsp_oldwithnew[certificate to be returned in oldWithNew field of genp]:file_or_uri:_files' \
    '-poll_count[number of times the client must poll before receiving a certificate]:number' \
    '-check_after[checkAfter value to include in poll response]:number' \
    '-grant_implicitconf[grant implicit confirmation of newly enrolled certificate]' \
    '-pkistatus[PKIStatus to be include in server response]:number' \
    '-failure[a single failure info bit number to be include in server response]:number' \
    '-failurebits[number representing failure bits to be include in server response]:number' \
    '-statusstring[text to be include as status string in server response]:str' \
    '-send_error[force server to reply with error message]' \
    '-send_unprotected[send reponse message without CMP-level protection]' \
    '-send_unprot_err[server shall send unprotected error message]' \
    '-accept_unprotected[accept missing or invalid protection of requests]' \
    '-accept_unprot_err[accept unprotected error messages from client]' \
    '-accept_raverified[accept RAVERIFIED as proof of possession(POPO)]' \
    $openssl_verification_options[@]
}

_openssl_cmp_verbosity_level() {
  local -a levels=(
    '0:EMERG'
    '1:ALERT'
    '2:CRIT'
    '3:ERR'
    '4:WARN'
    '5:NOTE'
    '6:INFO(Default)'
    '7:DEBUG'
    '8:TRACE'
  )

  _describe -t levels 'levels' levels "$@"
}

_openssl_cmp_commands() {
  local -a commands=(
    "ir:Initialization Request"
    "cr:Certificate Request"
    "p10cr:PKCS#10 Certification Request (for legacy support)"
    "kur:Key Update Request"
    "rr:Revocation Request"
    "genm:General Message"
  )

  _describe -t commands 'commands' commands "$@"
}

_openssl_cmp_revocation_reasons() {
  local -a reasons=(
    '0:unspecified'
    '1:keyCompromise'
    '2:cACompromise'
    '3:affiliationChanged'
    '4:superseded'
    '5:cessationOfOperation'
    '6:certificateHold'
    '8:removeFromCRL'
    '9:privilegeWithdrawn'
    '10:aACompromise'
  )

  _describe -t reasons 'reasons' reasons "$@"
}

_openssl_cms() {
  local -a ciphers=($(openssl enc -list | tail -n +2 ))
  local -a cipher_flags=()
  for cipher in $ciphers[@]
  do
    cipher_flags+=("($ciphers)${cipher}[use ${cipher:1:u} to encrypt]")
  done

  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-config[config file]:file:_files' \
    '-encrypt[encrypt data for the given recipient certificates]' \
    '-decrypt[decrypt data using the supplied certificate and private key]' \
    '-sign[sign data using the supplied certificate and private key]' \
    '-verify[verify signed data]' \
    '-resign[resign a message]' \
    '-sign_receipt[generate and output a signed receipt for the supplied message]' \
    '-verify_receipt[verify a signed receipt in file receipt]:receipt:_files' \
    '-digest[digest in hexadecimal form instead of computing it]:digest' \
    '-digest_create[create a CMS DigestedData type]' \
    '-digest_verify[verify a CMS DigestedData type and output the content]' \
    '-compress[create a CMS CompressedData type]' \
    '-uncompress[uncompress a CMS CompressedData type and output the content]' \
    '-EncryptedData_encrypt[encrypt content using supplied symmetric key and algorithm]' \
    '-EncryptedData_decrypt[decrypt content using supplied symmetric key and algorithm]' \
    '-data_create[create a CMS Data type]' \
    '-data_out[Data type and output the content]' \
    '-cmsout[take an input message and write out a PEM encoded CMS structure]' \
    '-inform[input format of the CMS structure]:format:(DER PEM SMIME)' \
    '-outform[output format of the CMS structure]:format(DER PEM SMIME)' \
    '-rctform[signed receipt format for use with the -receipt_verify]:format:(DER PEM SMIME)' \
    '(-stream -indef -noindef)'{-stream,-indef}'[enable streaming I/O for encoding operations]' \
    '(-stream -indef -noindef)-noindef[disable streaming I/O for encoding operations]' \
    '-binary[do not convert to canonical format]' \
    '-crlfeol[use CRLF instead of LF as end of line]' \
    '-asciicrlf[strip trailing whitespace from all lines, delete trailing blank lines at EOF]' \
    '-pwri_password[password for recipient]' \
    '-secretkey[symmetric key to use]:key' \
    '-secretkeyid[key identifier for the supplied symmetric key for KEKRecipientInfo type]:id' \
    '-inkey[private key file or URI to use when signing or decrypting]:file_or_uri:_files' \
    '-passin[private key password source]:option:_openssl_pass_phrase_options' \
    '*-keyopt[options for signing and encryption]:option' \
    '-keyform[format of the private key file]:format:(DER PEM P12 ENGINE)' \
    $openssl_provider_options[@] \
    $openssl_random_state_options[@] \
    '-originator[originator of the encrypted message]:file:_files' \
    '-recip[recipient of the certificate when decrypting a message]:file:_files' \
    $cipher_flags[@] \
    '-wrap[cipher algorithm to use for key wrap]:cipher:_openssl_cipher_algorithms' \
    '-debug_decrypt[set the CMS_DEBUG_DECRYPT flag]' \
    '-md[digest algorithm to use when signing or resigning]:digest:_openssl_digests' \
    '-signer[a signing certificate]:file:_files' \
    '-certfile[additional certificates]:file:_files' \
    '-cades[add an ESS signingCertificate or ESS signingCertificateV2 attributes to the SignerInfo]' \
    '-nodetach[use opaque signing]' \
    '-nocerts[do not include signers certificate when signing]' \
    '-noattr[do not include any signed attributes]' \
    '-nosmimecap[exclude list of supported algorithms from signed attributes]' \
    '-no_signing_time[exclude the signing time from signed attributes]' \
    '-receipt_request_all[requests should be provided by all recipient]' \
    '-receipt_request_first[requests should be provided by first tier recipients]' \
    '-receipt_request_from[add an explicit email address where receipts should be supplied]:email_address' \
    '-receipt_request_to[add an explicit email address where signed receipts should be sent to]:email_address' \
    '-signer[signer certificate file]:file:_files' \
    '-content[supply or override content for detached signature]:file:_files' \
    '-no_content_verify[do not verify signed content signatures]' \
    '-no_attr_verify[do not verify signed attribute signatures]' \
    '-nosigs[do not verify message signature]' \
    '-noverify[do not verify the signers certificate of a signed message]' \
    '-nointern[do not search certificates in message for signer]' \
    '-cades[require and check signer certificate digest]' \
    '-verify_retcode[exit non-zero on verification failure]' \
    $openssl_trusted_certificate_options[@] \
    '-keyid[subject key identifier to identify certificates instead of issuer name and serial number]' \
    '-econtent_type[encapsulated content type]:type' \
    '-text[add plain text MIME headers to the supplied message]' \
    '-certsout[output file name to any certificates contained in the input message]:file:_files' \
    '-to[TO email header]:to' \
    '-from[FROM email header]:from' \
    '-subject[SUBJECT email header]:subject' \
    '-noout[do not output the parsed CMS structure]' \
    '-print[print out all fields of the CMS structure]' \
    '-nameopt[printing options for string fields]:nameopt:_openssl_name_display_options' \
    '-receipt_request_print[print out the contents of any signed receipt requests]' \
    $openssl_verification_options[@] \
    '*::recipient_cert:_files'
}

_openssl_crl() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[CRL input format]:format:(DER PEM)' \
    '-outform[CRL output format]:format:(DER PEM)' \
    '-key[private key to be used to sign the CRL]:key:_files' \
    '-keyform[format of private key file]:format:(DER PEM P12)' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-gendelta[output a comparison of the main CRL and this file]:file:_files' \
    '-badsig[corrupt the signature before writing it]'\
    '-dateopt[date output format]:format:(rfc_822 iso_8601)' \
    '-text[print out the CRL in text form]' \
    '-verify[verify the signature in the CRL]' \
    '-noout[do not output the encoded version of the CRL]' \
    '-fingerprint[output the fingerprint of the CRL]' \
    '-crlnumber[output the number of the CRL]' \
    '-hash[output a hash of the issuer name]' \
    '-hash_old[output the hash of the CRL issuer name using the older algorithm]' \
    '-issuer[output the issuer name]' \
    '-lastupdate[output the lastUpdate field]' \
    '-nextupdate[output the nextUpdate field]' \
    '-nameopt[specify how the subject or issuer names are displayed]:option:_openssl_name_display_options' \
    $openssl_trusted_certificate_options[@] \
    $openssl_provider_options[@]
}

_openssl_crl2pkcs7() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[input format of the CRL]:format:(DER PEM)' \
    '-outform[output format of the PKCS#7 object]:format:(DER PEM)' \
    '-in[input file name to read a CRL from]:file:_files' \
    '-out[output file name to write the PKCS#7 structure]:file:_files' \
    '-certfile[file containing one or more certificates in PEM format]:file:_files' \
    '-nocrl[no CRL is included in the output file]' \
    $openssl_provider_options[@]
}

_openssl_dgst() {
  local not_need_digest_flags=$1
  local -a digest_flags=()

  if (( not_need_digest_flags != 1 )); then
    local -a digests=($(openssl dgst -list | tail -n +2))
    for digest in $digests[@]
    do
      digest_flags+=("${digest}[use ${digest:1} message digest algorithm]")
    done
  fi

  _arguments \
    '(- *)-help[print help message]' \
    $digest_flags[@] \
    '(- *)-list[print out a list of supported message digests]' \
    '-c[print out the digest in two digit groups separated by colons]' \
    '(-d --debug)'{-d,--debug}'[print out BIO debugging information]' \
    '-hex[digest is to be output as a hex dump]' \
    '-binary[output the digest or signature in binary form]' \
    '-xoflen[output length for XOF algorithms]:length' \
    '-r[output the digest in the "coreutils" format]' \
    '-out[output file name]:file:_files' \
    '-sign[private key file or URI to sign the digest]:file_or_uri:_files' \
    '-keyform[format of the key to sign with]:format:(DER PEM P12 ENGINE)' \
    '-sigopt[options of signature algorithms during sign or verify operations]:options' \
    '-passin[private key password source]:source:_openssl_pass_phrase_options' \
    '-verify[public key file to verify the signature]:file:_files' \
    '-prverify[private key file to verify the signature]:file:_files' \
    '-signature[actual signature file to verify]:file:_files' \
    '-hmac[key to create a hashed MAC]:key' \
    '-mac[MAC algorithm]:alg:_openssl_mac_algorithms' \
    '-macopt[options of MAC algorithm]:options' \
    '-fips-fingerprint[compute HMAC using a specific key for certain OpenSSL-FIPS operations]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '*::file:_files'
}

_openssl_dhparam() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[input format(default is PEM)]:format:(DER PEM)' \
    '-outform[output format(default is PEM)]:format:(DER PEM)' \
    '-in[input file name to read a CRL from]:file:_files' \
    '-out[output file name to write the PKCS#7 structure]:file:_files' \
    '-dsaparam[read or create DSA parameters]' \
    '-check[perform numerous checks to see]' \
    '(-2 -3 -5)-2[generator use 2]' \
    '(-2 -3 -5)-3[generator use 3]' \
    '(-2 -3 -5)-5[generator use 5]' \
    '-noout[inhibit the output of the encoded version of the parameters]' \
    '-text[print out the DH parameters in human readable form]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-quiet[suppress the output of progress messages]' \
    '*::numbits'
}

_openssl_dsa() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[key input format]:format:(DER PEM)' \
    '-outform[key output format(default: PEM)]:format:(DER PEM)' \
    '-in[input file name]:file:_files' \
    '-out[output file name to write a key]:file:_files' \
    '-passin[password source for input file]:source:_openssl_pass_phrase_options' \
    '-passout[password source for output file]:source:_openssl_pass_phrase_options' \
    '-aes128[encrypt the private key with aes128 before outputting it]' \
    '-aes192[encrypt the private key with aes192 before outputting it]' \
    '-aes256[encrypt the private key with aes256 before outputting it]' \
    '-aria128[encrypt the private key with aria128 before outputting it]' \
    '-aria192[encrypt the private key with aria192 before outputting it]' \
    '-aria256[encrypt the private key with aria256 before outputting it]' \
    '-camellia128[encrypt the private key with camellia128 before outputting it]' \
    '-camellia192[encrypt the private key with camellia192 before outputting it]' \
    '-camellia256[encrypt the private key with camellia256 before outputting it]' \
    '-des[encrypt the private key with des before outputting it]' \
    '-des3[encrypt the private key with des3 before outputting it]' \
    '-idea[encrypt the private key with idea before outputting it]' \
    '-text[print out the public, private key components and parameters]' \
    '-noout[prevent output of the encoded version of the key]' \
    '-modulus[print out the value of the public key component of the key]' \
    '-pubin[read public key instead of private key]' \
    '-pubout[output public key instead of private key]' \
    '-pvk-strong[enable "Strong" PVK encoding level]' \
    '-pvk-weak[enable "Weak" PVK encoding level]' \
    '-pvk-none[do not enforce PVK encoding]' \
    $openssl_provider_options[@]
}

_openssl_dsaparam() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[DSA parameters input format]:format:(DER PEM)' \
    '-outform[DSA parameters output format]:format:(DER PEM)' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-noout[inhibit the output of the encoded version of the parameters]' \
    '-text[print out the DSA parameters in human readable form]' \
    '-genkey[generate a DSA either using the specified or generated parameters]' \
    '-verbose[print extra details about the operations being performed]' \
    '-quiet[print fewer details about the operations being performed]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '1:numbits' \
    '2:numqbits'
}

_openssl_ec() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[key input format]:format:(DER PEM P12 ENGINE)' \
    '-outform[key output format]:format:(DER PEM)' \
    '-in[input file name or input URI]:file_or_uri:_files' \
    '-out[output file name]:file:_files' \
    '-passin[passowrd source for input file]:source:_openssl_pass_phrase_options' \
    '-passout[passowrd source for output file]:source:_openssl_pass_phrase_options' \
    '-des[encrypt the private key with DES]' \
    '-des3[encrypt the private key with DES3]' \
    '-idea[encrypt the private key with IDEA]' \
    '-text[print out the public, private key components and parameters]' \
    '-noout[prevents output of the encoded version of the key]' \
    '-param_out[print the elliptic curve parameters]' \
    '-pubin[read public key from the input instead of private key]' \
    '-pubout[output public key instead of private key]' \
    '-conv_form[how to convert points on the elliptic curve]:how:(compressed uncompressed hybrid)' \
    '-param_enc[how to encode the elliptic curve parameters]:how:(named_curve explicit)' \
    '-no_public[omit the public key components from the private key output]' \
    '-check[check the consistency of an EC private or public key]' \
    $openssl_provider_options[@]
}

_openssl_ecparam() {
  local -a short_names=($(openssl ecparam -list_curves | awk -F: '/^\s+\S+\s*:/{ print $1 }'))

  _arguments \
    '(- *)-help[print help message]' \
    '-inform[EC parameters input format]:format:(DER PEM)' \
    '-outform[EC parameters output format]:format:(DER PEM)' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-noout[inhibit the output of the encoded version of the parameters]' \
    '-text[print out the EC parameters in human readable form]' \
    '-check[validate the elliptic curve parameters]' \
    '-check_named[validate the elliptic name curve parameters]' \
    '-name[use the EC parameters with the specified short name]:name:(($short_names))' \
    '-list_curves[print out a list of all currently implemented EC parameters name]' \
    '-conv_form[specify how the points on the elliptic curve are converted into octet strings]:type:(compressed uncompressed hybrid)' \
    '-param_enc[specify the how the elliptic curve parameters are encoded]:type:(named_curve explicit)' \
    '-no_seed[inhibit that the seed for the parameter generation]' \
    '-genkey[generate an EC private key]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@]
}

_openssl_enc() {
  local not_need_cipher_flags=$1
  local -a cipher_flags=()

  if (( not_need_cipher_flags != 1 )); then
    local -a ciphers=($(openssl enc -list | tail -n +2 ))

    for cipher in $ciphers[@]
    do
      cipher_flags+=("($ciphers)${cipher}[use ${cipher:1}]")
    done
  fi

  _arguments  \
    '(- *)-help[print help message]' \
    '(- *)'{-list,-ciphers}'[list all supported ciphers]' \
    $cipher_flags[@] \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-pass[password source]:source:_openssl_pass_phrase_options' \
    '-e[encrypt the input data(default behavior)]' \
    '-e[decrypt the input data]' \
    '(-a -base64)'{-a,-base64}'[Base64 proess the data]' \
    '-A[base64 encoding produces output without any newline character]' \
    '-k[password to derive the key from]:password' \
    '-kfile[file to read the password from the first line]:file:_files' \
    '-md[digest to create the key from the passphrase]:digest:(md2 md5 sha1 shar256)' \
    '-iter[interation count on the password in deriving the encryption key]:count' \
    '-pbkdf2[use PBKDF2 algorithm with a default iteration count of 10000]' \
    '-saltlen[salt length to use when using th -pbkdf2 option]:length' \
    '-nosalt[do not use a salt in the key derivation routines]' \
    '-salt[use salt when encrypting]' \
    '-S[actual salt to use]:salt' \
    '-K[actual key to use]:key' \
    '-iv[actual IV to use]:iv' \
    '-p[print out the key and IV used]' \
    '-P[print out the key and IV used then immediately exit]' \
    '-bufsize[buffer size of I/O]:size' \
    '-nopad[disable standard block padding]' \
    '-v[verbose print]' \
    '-debug[debug the BIOs used for I/O]' \
    '-z[compress or decompress encrypted data using zlib after encrypting or before decryption]' \
    '-none[use NULL cipher]' \
    '-skeymgmt[name of the EVP_SKEYMGMT to be used]:name' \
    '-skeyopt[opaque symmetric key options]:options' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@]
}

_openssl_errstr() {
  _arguments \
    '(- *)-help[print help message]' \
    '*:error_code'
}

_openssl_fipsinstall() {
  _arguments \
    '(- *)-help[print help message]' \
    '-module[file name of the FIPS module]:file:_files' \
    '-out[file name to output configuration data to]:file:_files' \
    '-in[input file name to load configuration data from]:_files' \
    '-verify[verify the input configuration file]' \
    '-provider_name[name of the provider inside the configuration file(default: "fips")]:name' \
    '-section_name[name of the section inside the configuration file(default: "fips_sect")]:name' \
    '-mac_name[name of a supported MAC algorithm]:name:_openssl_mac_algorithms' \
    '-macopt[options of the MAC algorithm]:option' \
    '-noout[disable logging of the self tests]' \
    '-pedantic[strictly FIPS compliant]' \
    '-no_conditional_errors[not enter an error state]' \
    '-no_security_checks[not perform run-time security checks]' \
    '-ems_check[enable a run-time Extended Master Secret]' \
    '-no_short_mac[not allow short MAC outputs]' \
    '-hmac_key_check[not allow small keys sizes when using HMAC]' \
    '-kmac_key_check[not allow small keys sizes when using KMAC]' \
    '-no_drbg_truncated_digests[not allow truncated digests with Hash and HMAC DRBGs]' \
    '-signature_digest_check[enforce signature algorithms to use digests]' \
    '-tls13_kdf_digest_check[enable a run-time digest check when deriving a key by TLS13 KDF]' \
    '-tls1_prf_digest_check[enable a run-time digest check when deriving a key by TLS_PRF]' \
    '-sshkdf_digest_check[enable a run-time digest check when deriving a key by SSHKDF]' \
    '-x963kdf_digest_check[enable a run-time digest check when deriving a key by X963KDF]' \
    '-dsa_sign_disabled[not allow DSA signing]' \
    '-tdes_encrypt_disabled[not allow Triple-DES encryption]' \
    '-rsa_pkcs15_padding_disabled[not allow PKCS#1 version 1.5 padding]' \
    '-rsa_pss_saltlen_check[enable a run-time salt length check]' \
    '-rsa_sign_x931_disabled[not allow X9.31 padding]' \
    '-hkdf_key_check[enable a run-time short key-derivation key check when deriving a key by HKDF]'\
    '-kbkdf_key_check[enable a run-time short key-derivation key check when deriving a key by KBKDF]'\
    '-tls13_kdf_key_check[enable a run-time short key-derivation key check when deriving a key by TLS13 KFD]'\
    '-tls1_prf_key_check[enable a run-time short key-derivation key check when deriving a key by TLS_PRF]'\
    '-sshkdf_key_check[enable a run-time short key-derivation key check when deriving a key by SSHKDF]'\
    '-sskdf_key_check[enable a run-time short key-derivation key check when deriving a key by SSKDF]'\
    '-x963kdf_key_check[enable a run-time short key-derivation key check when deriving a key by X963KDF]'\
    '-x942kdf_key_check[enable a run-time short key-derivation key check when deriving a key by X942KDF]'\
    '-no_pbkdf2_lower_bound_check[not perform run-time lower bound check for PBKDF2]' \
    '-ecdh_cofactor_check[enable a run-time check that ECDH uses the EC curves cofactor value]' \
    '-self_test_onload[do not write two fields related to "test status indicator" and "MAC status indicator"]' \
    '-self_test_oninstall[ write two fields related to "test status indicator" and "MAC status indicator]' \
    '-quiet[do not output pass/fail messages]' \
    '-corrupt_desc[currupt description to be used to test failure]:description' \
    '-corrupt_type[currupt type to be used to test failure]:type' \
    '-config[configuration file]:file:_files'
}

_openssl_gendsa() {
  _arguments \
    '(- *)-help[print help message]' \
    '-out[output file name]' \
    '-passout[passphrase used for the output file]:option:_openssl_pass_phrase_options'\
    '-aes128[encrypt the private key with aes128 before outputting it]' \
    '-aes192[encrypt the private key with aes192 before outputting it]' \
    '-aes256[encrypt the private key with aes256 before outputting it]' \
    '-aria128[encrypt the private key with aria128 before outputting it]' \
    '-aria192[encrypt the private key with aria192 before outputting it]' \
    '-aria256[encrypt the private key with aria256 before outputting it]' \
    '-camellia128[encrypt the private key with camellia128 before outputting it]' \
    '-camellia192[encrypt the private key with camellia192 before outputting it]' \
    '-camellia256[encrypt the private key with camellia256 before outputting it]' \
    '-des[encrypt the private key with des before outputting it]' \
    '-des3[encrypt the private key with des3 before outputting it]' \
    '-idea[encrypt the private key with idea before outputting it]' \
    '-verbose[print extra details about the operations being performed]' \
    '-quiet[print fewer details about the operations being performed]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '*:paramfile:_files'
}

_openssl_genpkey() {
  local -a builtin_algorithms=(
    RSA DSA DH DHX EC
    RSA RSA-PSS EC X25519 X448 ED25519 ED448
    ML-DSA-44 ML-DSA-5 ML-DSA-87
    ML-KEM-512 ML-KEM-768 ML-KEM-1024
  )

  local -a ciphers=($(openssl enc -list | tail -n +2 ))
  local -a cipher_flags=()
  for cipher in $ciphers[@]
  do
    cipher_flags+=("($ciphers)${cipher}[use ${cipher:1}]")
  done

  _arguments \
   '(- *)-help[print help message]' \
   '-out[output private key file]:file:_files' \
   '-outpubkey[output public key file]:file:_files' \
   '-outform[output format]:format:(DER PEM)' \
   '-verbose[output "status dots" while generating keys]' \
   '-quiet[do not output "status dots" while generating keys]' \
   '-pass[output file password source]:source:_openssl_pass_phrase_options' \
   $cipher_flags[@] \
   '-algorithm[public key algorithm]:alg:(($builtin_algorithms))' \
   '-pkeyopt[public key algorithm option]:option' \
   '-genparam[generate a set of parameters instead of a private key]' \
   '-paramfile[file to supply public key parameters]:file:_files' \
   '-text[print an (unencrypted) text representation of private and public keys and parameters]' \
   $openssl_random_state_options[@] \
   $openssl_provider_options[@] \
   '-config[configuration file]:file:_files'
}

_openssl_genrsa() {
  _arguments \
    '(- *)-help[print help message]' \
    '-out[output key file name]:file:_files' \
    '-passout[output file password source]:source:_openssl_pass_phrase_options' \
    '-aes128[encrypt the private key with AES128]' \
    '-aes192[encrypt the private key with AES192]' \
    '-aes256[encrypt the private key with AES256]' \
    '-aria128[encrypt the private key with ARIA128]' \
    '-aria192[encrypt the private key with ARIA192]' \
    '-aria256[encrypt the private key with ARIA256]' \
    '-camellia128[encrypt the private key with CAMELLIA128]' \
    '-camellia192[encrypt the private key with CAMELLIA192]' \
    '-camellia256[encrypt the private key with CAMELLIA256]' \
    '-des[encrypt the private key with DES]' \
    '-des3[encrypt the private key with DES3]' \
    '-idea[encrypt the private key with IDEA]' \
    '(-F4 -f4)'{-F4,-f4}'[use 65537 as public exponent]' \
    '-primes[specify the number of primes to use while generating the RSA key]:num' \
    '-verbose[print extra details about the operations being performed]' \
    '-quiet[print fewer details about the operations being performed]' \
    '-traditional[write the key using the traditional PKCS#1 format]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '::numbits'
}

_openssl_help() {
  local -a commands=(
    # Standard commands
    asn1parse ca ciphers cmp
    cms crl crl2pkcs7 dgst
    dhparam dsa dsaparam ec
    ecparam enc engine errstr
    fipsinstall gendsa genpkey genrsa
    help info kdf list
    mac nseq ocsp passwd
    pkcs12 pkcs7 pkcs8 pkey
    pkeyparam pkeyutl prime rand
    rehash req rsa rsautl
    s_client s_server s_time sess_id
    skeyutl smime speed spkac
    srp storeutl ts verify
    version x509

    # Message Digest commands (see the `dgst' command for more details)
    blake2b512 blake2s256 md4 md5
    rmd160 sha1 sha224 sha256
    sha3-224 sha3-256 sha3-384 sha3-512
    sha384 sha512 sha512-224 sha512-256
    shake128 shake256 sm3

    # Cipher commands (see the `enc' command for more details)
    aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
    aes-256-cbc aes-256-ecb aria-128-cbc aria-128-cfb
    aria-128-cfb1 aria-128-cfb8 aria-128-ctr aria-128-ecb
    aria-128-ofb aria-192-cbc aria-192-cfb aria-192-cfb1
    aria-192-cfb8 aria-192-ctr aria-192-ecb aria-192-ofb
    aria-256-cbc aria-256-cfb aria-256-cfb1 aria-256-cfb8
    aria-256-ctr aria-256-ecb aria-256-ofb base64
    bf bf-cbc bf-cfb bf-ecb
    bf-ofb camellia-128-cbc camellia-128-ecb camellia-192-cbc
    camellia-192-ecb camellia-256-cbc camellia-256-ecb cast
    cast-cbc cast5-cbc cast5-cfb cast5-ecb
    cast5-ofb des des-cbc des-cfb
    des-ecb des-ede des-ede-cbc des-ede-cfb
    des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb
    des-ede3-ofb des-ofb des3 desx
    rc2 rc2-40-cbc rc2-64-cbc rc2-cbc
    rc2-cfb rc2-ecb rc2-ofb rc4
    rc4-40 seed seed-cbc seed-cfb
    seed-ecb seed-ofb sm4-cbc sm4-cfb
    sm4-ctr sm4-ecb sm4-ofb zlib
    zstd
  )

  _values commands $commands
}

_openssl_info() {
  _arguments \
    '(- *)-help[print help message]' \
    '-configdir[outputs the default directory for OpenSSL configuration files]' \
    '-enginesdir[outputs the default directory for OpenSSL engine modules]' \
    '-modulesdir[outputs the default directory for OpenSSL dynamically loadable modules]' \
    '-dsoext[outputs the DSO extension OpenSSL uses]' \
    '-dirnamesep[outputs the separator character between a directory specification and a filename]' \
    '-listsep[outputs the OpenSSL list separator character]' \
    '-seeds[outputs the randomness seed sources]' \
    '-cpusettings[outputs the OpenSSL CPU settings info]' \
    '-windowscontext[outputs the Windows install context]'
}

_openssl_list() {
  _arguments \
    '(- *)-help[print help message]' \
    '-verbose[displays extra information]' \
    '-select[only list algorithms that match this name]:name' \
    '-1[list the commands, digest-commands, or cipher-commands in a single column]' \
    '-all-algorithms[display lists of all algorithms]' \
    '-commands[display a list of standard command]' \
    '-standard-commands[display list of standard commands]' \
    '-digest-commands[display a list of message digest commands(deprecated)]' \
    '-cipher-commands[display a list of cipher commands(deprecated)]' \
    '-cipher-algorithms[display a list of symmetric cipher algorithms]' \
    '-digest-algorithms[display a list of digest algorithms]' \
    '-kdf-algorithms[display a list of kdf algorithms]' \
    '-mac-algorithms[display a list of mac algorithms]' \
    '-random-instances[list the primary, public and private random number generator details]' \
    '-random-generators[display a list of random number generators]' \
    '-encoders[display a list of encoders]' \
    '-decoders[display a list of decoders]' \
    '-public-key-algorithms[display a list of public key algorithms]' \
    '-public-key-methods[display a list of public key methods]' \
    '-key-managers[display a list of key managers]' \
    '-skey-managers[display a list of symmetric key managers]' \
    '-key-exchange-algorithms[display a list of key exchange algorithms]' \
    '-kem-algorithms[display a list of key encapsulation algorithms]' \
    '-tls-groups[display a list of the IANA names of all available TLS groups]' \
    '-all-tls-groups[display a list of the names of all available TLS groups]' \
    '-tls1_2[list TLS groups compatible with TLS 1.2]'\
    '-tls1_3[list TLS groups compatible with TLS 1.3]'\
    '-signature-algorithms[display a list of signature algorithms]' \
    '-tls-signature-algorithms[display the list of signature algorithms available for TLS handshakes]' \
    '-asymcipher-algorithms[display a list of asymmetric cipher algorithms]' \
    '-store-loaders[display a list of store loaders]' \
    '-providers[display a list of all loaded providers with their names, version and status]' \
    '-disabled[display a list of disabled features]' \
    '-objects[display a list of built in objects]' \
    '-options[output a two-column list of the options accepted by the specified command]:command:_openssl_help' \
    $openssl_provider_options[@]
}

_openssl_mac() {
  local -a cbc_or_gcm_ciphers=(
    AES-128-CBC AES-192-CBC AES-256-CBC
    AES-128-GCM AES-192-GCM AES-256-GCM
  )

  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name to calculate a MAC]:file:_files' \
    '-out[output file name]:file:_files' \
    '-binary[output the MAC in binary form]' \
    '-cipher[specify the cipher algorithm]:ciper:(($cbc_or_gcm_ciphers))' \
    '-digest[use HMAC as an alphanumeric string]:name:_openssl_digests' \
    '-macopt[options to the MAC algorithm]:options:_openssl_macopts' \
    $openssl_provider_options[@] \
    '*:mac_name:_openssl_mac_algorithms'
}

_openssl_nseq() {
  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name to read]:file:_files' \
    '-out[output file name]:file:_files' \
    '-toseq[output Netscape certificate sequence]' \
    $openssl_provider_options[@]
}

_openssl_ocsp() {
  local -a digests=($(openssl dgst -list | tail -n +2))
  local -a digest_flags=()
  for digest in $digests[@]
  do
    digest_flags+=("${digest}[use ${digest:1} message digest algorithm]")
  done

  _arguments \
    '(- *)-help[print help message]' \
    '-out[output file name]:file:_files' \
    '-issuer[specify the current issuer certificate]:file:_files' \
    '-cert[certificate file name to request]:file:_files' \
    '-no_certs[do not include any certificates in signed request]' \
    '-serial[serial number of certificate]:num' \
    '-signer[signer to sign the OSCP request]:file:_files' \
    '-signkey[private key to sign the OCSP request]:file:_files' \
    '-sign_other[additional certificates to include in the signed request]:file:_files' \
    '(-nonce -no_nonce)-nonce[add an OCSP nonce extension to a request]' \
    '(-nonce -no_nonce)-no-nonce[disable OCSP nonce addition]' \
    '-req_text[print out the text form of the OCSP request]' \
    '-resp_text[print out the text form of the OCSP response]' \
    '-text[print out the text form of the OCSP both request and response]' \
    '-reqout[write out the DER-encoded OCSP request to file]:file:_files' \
    '-respout[write out the DER-encoded OCSP response to file]:file:_files' \
    '-reqin[read OCSP request from file]:file:_files' \
    '-respin[read OCSP response from file]:file:_files' \
    '-url[responder host and optionally port and path via a URL]:url:_urls' \
    '-host[host and port to be sent the OCSP request]:host' \
    '-path[HTTP path to be sent the OCSP request]:path' \
    '-proxy[HTTP(S) proxy server to use for reaching the OCSP server]:address' \
    '-no_proxy[list of IP addresses and DNS names of servers not to use an HTTP(S) proxy for]:addresses' \
    '*-head[add the header name with the specified value to the OCSP request]:key_value' \
    '-timeout[connection timeout to the OCSP responder in seconds]:seconds' \
    '-verify_other[file or URI containing additional certificates to search for signer]:file:_files' \
    '-trust_other[do not verify additional certificates]' \
    '-VAfile[file or URI containing explicitly trusted responder certificates]:file:_files' \
    '-noverify[do not attempt to verify the OCSP response signature or the nonce values]' \
    '-no_intern[ignore certificates contained in the OCSP response]' \
    '-no_signature_verify[do not check the signature on the OCSP response]' \
    '-no_cert_verify[do not verify the OCSP response signers certificate at all]' \
    '-no_chain[do not use certificates in the response as additional untrusted CA certificates]' \
    '-no_explicit[do not explicitly trust the root CA]' \
    '-no_cert_checks[do not perform any additional checks on the OCSP response signers certificate]' \
    '-validity_period[acceptable error range in seconds]:nsec' \
    '-status_age[maximum status age in seconds]:seconds: ' \
    '-rcid[digest algorithm to use for certificate identification in the OCSP response]:digest:_openssl_digests' \
    $digest_flags[@] \
    $openssl_trusted_certificate_options[@] \
    $openssl_verification_options[@] \
    $openssl_provider_options[@] \
    '-index[index file parameter]:file:_files' \
    '-CA[index file of CA certificate corresponding to the revocation information]:file:_files' \
    '-rsigner[certificate to sign OCSP responses with]:file:_files' \
    '-rkey[private key to sign OCSP responses with]:file:_files' \
    '-passin[private key password source]:source:_openssl_pass_phrase_options' \
    '-rother[additional certificates to include in the OCSP response]:file:_files' \
    '-rsigopt[pass options to the signature algorithm when signing OCSP responses]:option' \
    '-rmd[digest to use when signing the reponse]:digest:_openssl_digests' \
    '-badsig[corrupt the response signature before writing it]' \
    '-resp_no_certs[do not include any certificates in the OCSP response]' \
    '-resp_key_id[identify the signer certificate using the key ID]'\
    '-port[port to listen for OCSP requests on]:port' \
    '-ignore_err[ignore malformed requests or responses]' \
    '-nrequest[request number that OCSP server will exit after this number of requests]:number' \
    '-multi[run the specified number of OCSP responder child processes]:process_count' \
    '-nmin[number of minites when fresh revocation information]:minites' \
    '-nmin[number of days when fresh revocation information]:minites'
}

_openssl_passwd() {
  _arguments \
    '(- *)-help[print help message]' \
    '-1[use the MD5 based BSD password algorithms(default)]' \
    '-apr[use the apr1 algorithms(Apache variant of the BSD algorithm)]' \
    '-aixmd5[use the AIX MD5 algorithm]' \
    '-5[use the SHA256 based algorithms defined by Ulrich Drepper]' \
    '-6[use the SHA512 based algorithms defined by Ulrich Drepper]' \
    '-salt[use the specified salt]:salt' \
    '-in[read passwords from file]:file' \
    '-stdin[read passwords from stdin]' \
    '-noverify[do not verify when reading a password from the terminal]' \
    '-quiet[do not output warnings when passwords given at the command line are truncated]' \
    '-table[format output as table]' \
    '-reverse[when the -table -option is used, reverse the order of cleartext and hash]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '*::password'
}

_openssl_pkcs12() {
  _arguments \
    '(- *)-help[print help message]' \
    '-passin[input password source]:source:_openssl_pass_phrase_options' \
    '-passout[output password source]:source:_openssl_pass_phrase_options' \
    '-password[password source]:source:_openssl_pass_phrase_options' \
    '-twopass[prompt for separate integrity and encryption passwords]' \
    '-nokeys[no private keys will be output]' \
    '-nocerts[no certificates will be output]' \
    '-noout[inhibit all credentials output]' \
    '-legacy[use legacy mode of operation and automatically load the legacy provider]' \
    $openssl_provider_options[@] \
    $openssl_random_state_options[@] \
    '-in[input file name or URI]:file_or_uri:_files' \
    '-out[output file name]:file:_files' \
    '-info[output additional information about the PKCS#12]' \
    '-nomacver[do not attempt to verify the integrity MAC]' \
    '-clcerts[only output client certificates]' \
    '-cacerts[only output CA certificates]' \
    '-aes128[encrypt the private key with AES128]' \
    '-aes192[encrypt the private key with AES192]' \
    '-aes256[encrypt the private key with AES256]' \
    '-aria128[encrypt the private key with ARIA128]' \
    '-aria192[encrypt the private key with ARIA192]' \
    '-aria256[encrypt the private key with ARIA256]' \
    '-camellia128[encrypt the private key with CAMELLIA128]' \
    '-camellia192[encrypt the private key with CAMELLIA192]' \
    '-camellia256[encrypt the private key with CAMELLIA256]' \
    '-des[encrypt the private key with DES]' \
    '-des3[encrypt the private key with DES3]' \
    '-idea[encrypt the private key with IDEA]' \
    '-noenc[do not encrypt private keys at all]' \
    '-export[create PKCS#12 file rather than parsed]' \
    '-inkey[private key input file or URI for PKCS12 output]:file_or_uri:_files' \
    '-certfile[extra certificates input file]:file:_files' \
    '-passcerts[password source for certificate input]:source:_openssl_pass_phrase_options' \
    '-chain[certificate chain is built and included in the PKCS#12 output file]' \
    '-untrusted[untrusted certificates input file]:file:_files' \
    $openssl_trusted_certificate_options[@] \
    '-name["friendly name" for the certificates and private key]:name' \
    '-caname["friendly name" for other certificates]:name' \
    '-CSP[name as a Microsoft CSP name]:name' \
    '-LMK[add the "Local Key Set" identifier to the attributes]' \
    '-keyex[private key is to be used for key exchange]' \
    '-keysig[private key is to be used for just signing]' \
    '-keypbe[algorithm used to encrypt the private key]:alg:_openssl_cipher_algorithms' \
    '-certpbe[algorithm used to encrypt certificates]:alg:_openssl_cipher_algorithms' \
    '-descert[encrypt the certificates using triple DES]' \
    '-macalg[MAC digest algorithm]:digest:_openssl_digests' \
    '-pbmac1_pbkdf2[use PBMAC1 with PBKDF2 for MAC protection]' \
    '-pbmac1_pbkdf2_md[PBKDF2 KDF digest algorithm]:alg:_openssl_digests' \
    '-iter[iteration count for the encryption key and MAC]:count' \
    '-noiter[set iteration count to 1 for encryption]' \
    '-nomaciter[set iteration count to 1 for MAC]' \
    '-macsaltlen[salt length in bytes for the MAC]:length' \
    '-nomac[do not attempt to provide the MAC integrity]' \
    '-jdktrust[export pkcs12 file in a foormat compatible with Java keystore usage]:usage:(anyExtendedKeyUsage)'
}

_openssl_pkcs7() {
  _arguments \
   '(- *)-help[print help message]' \
   '-inform[input format]:format:(DER PEM)' \
   '-outform[output format]:format:(DER PEM)' \
   '-in[input file name]:file:_files' \
   '-out[output file name]:file:_files' \
   '-print[print out the full PKCS7 object]' \
   '-print_certs[print out any certificates or CRLs contained in the file]' \
   '-quiet[print out just the PEM-encoded certificates without any other output]' \
   '-text[print out certificate details in full]' \
   '-noout[do not output the encoded version of the PKCS#7 structure]' \
   $openssl_provider_options[@]
}

_openssl_pkcs8() {
  local -a prf_algorithms=(
    hmacWithMD5 hmacWithRMD160 hmacWithSHA1 hmacWithSHA224 hmacWithSHA256 hmacWithSHA384 hmacWithSHA512
  )

  _arguments \
   '(- *)-help[print help message]' \
   '-topk8[read a private key and write a PkCS#8 format key]' \
   '-inform[input format]:format:(DER PEM)' \
   '-outform[output format]:format:(DER PEM)' \
   '-traditional[traditional format]' \
   '-in[input file name]:file:_files' \
   '-passin[input password source]:source:_openssl_pass_phrase_options' \
   '-passout[output password source]:source:_openssl_pass_phrase_options' \
   '-out[output file name]:files:_files' \
   '-iter[number of iterations to create PKCS#8 containers]:count' \
   '-noiter[use 1 as iteration count]' \
   '-nocrypt[output unencrypted PrivateKeyInfo structure]' \
   '-v2[algorithm for PKCS#5 v2.0]:alg:_openssl_cipher_algorithms' \
   '-v2prf[PRF algorithm to use with PKCS#5 v2.0]:alg:(($prf_algorithms))' \
   '-v1[algorithm for PKCS#5 v1.5 or PKCS#12]:alg:_openssl_cipher_algorithms' \
   '-scrypt[use the script algorithm for private key encryption]' \
   '-scrypt_N[scrypt "N" parameter]:n' \
   '-scrypt_r[scrypt "r" parameter]:r' \
   '-scrypt_p[scrypt "p" parameter]:p' \
   '-saltlen[length of the salt to use for the PBE algorithm]:length' \
   $openssl_random_state_options[@] \
   $openssl_provider_options[@]
}

_openssl_pkey() {
  _arguments  \
   '(- *)-help[print help message]' \
   $openssl_provider_options[@] \
   '-check[check the consistency of a key pair for both public and private components]' \
   '-pubcheck[check the correctness of either a public key or the public components of a key pair]' \
   '-in[input file or URI]:file_or_uri:_files' \
   '-inform[key input format]:format:(DER PEM P12 ENGINE)' \
   '-passin[password source for the key input]:source:_openssl_pass_phrase_options' \
   '-pubin[read public key instead of private key]' \
   '-out[output file name]' \
   '-outform[key output format]:format:(DER PEM)' \
   '-cipher[cipher to encrypt the PEM encoded private key]:cipher:_openssl_ciphers' \
   '-passout[password source for the output file]:source:_openssl_pass_phrase_options' \
   '-traditional[use older "traditional" format]' \
   '-pubout[output the public components]' \
   '-noout[do not output the key in encoded form]' \
   '-text[output the various key components in plain text]' \
   '-text_pub[output only the public key components in text form]' \
   '-ec_conv_form[specify how the points on the elliptic-curve curve are converted into octet strings]:type:(compressed uncompressed hybrid)' \
   '-ec_param_enc[specify how the elliptic curve parameters are encoded]:type:(named_curve explicit)'
}

_openssl_pkeyparam() {
  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-text[print out the parameters in plain text]' \
    '-noout[do not output the encoded version of the parameters]' \
    '-check[check the correctness of parameters]' \
    $openssl_provider_options[@]
}

_openssl_pkeyutl() {
  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name]:file:_files' \
    '-rawin[indicate that signature or verification input data is raw data]' \
    '-digest[digest algorithm to be used to hash the input data]:digest:_openssl_digests' \
    '-out[output file name]:file:_files' \
    '-secret[shared-secret output file name]:file:_files' \
    '-sigfile[signature file]:file:_files' \
    '-inkey[input key file name or URI]:file_or_uri:_files' \
    '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
    '-passin[input key password source]:source:_openssl_pass_phrase_options' \
    '-pubin[read public key instead of private key]' \
    '-certin[input is a certificate containing a public key]' \
    '-rev[reverse the order of the input buffer]' \
    '-sign[sign the input data and output the signed result]' \
    '-verify[verify the input data against the signature]'\
    '-verifyrecover[verify the given signature and output the recovered data]' \
    '-encrypt[encrypt the input data using a public key]' \
    '-decrypt[decrypt the input data using a private key]' \
    '-derive[derive a shared secret using own private (EC)DH key and peer key]' \
    '-peerkey[file containing the peer public or private (EC)DH key]:file:_files' \
    '-peerform[peer key format]:format:(DER PEM P12 ENGINE)' \
    '-encap[use a Key Encapsulation Mechanism to encapsulate a shared-secret]' \
    '-decap[decode an encapsulated secret with a private key]' \
    '-kemop[specify KEM mode for key algorithm]:mode' \
    '-kdf[key derivation function algorithm]:algorithm:(TLS1-PRF HKDF)' \
    '-kdflen[output length for KDF]:length' \
    '-pkeyopt[public key options]:options' \
    '-pkeyopt_passin[public key option from stdin or a password source]:option:_openssl_pass_phrase_options' \
    '-hexdump[hex dump the output data]' \
    '-asn1parse[parse the ASN.1 output data to check its DER encoding]'\
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-config[configuration file]:file:_files'
}

_openssl_prime() {
  _arguments \
    '(- *)-help[print help message]' \
    '-hex[generate hex output]' \
    '-generate[generate a prime number]' \
    '-bits[how many bits to generate a prime]:num' \
    '-safe[generates a safe prime]' \
    $openssl_provider_options[@] \
    '*::number:'
}

_openssl_rand() {
  _arguments  \
    '(- *)-help[print help message]' \
    '-out[output file name]:file:_files' \
    '-base64[perform base64 encoding on the output]' \
    '-hex[show the output as a hex string]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '*:num'
}

_openssl_rehash() {
  _arguments \
    '(- *)-help[print help message]' \
    '-old[use old-tyle hashing for generating links]' \
    '-n[do not remove existing links]' \
    '-compat[generate links for both old-style(MD5) and new-style(SHA1) hashing]' \
    '-v[print messages about old links removed and new links created]' \
    $openssl_provider_options[@] \
    '*::dir:_files -/'
}

_openssl_req() {
  local -a digests=($(openssl dgst -list | tail -n +2))
  local -a digest_flags=()
  for digest in $digests[@]
  do
    digest_flags+=("($digests)${digest}[use ${digest:1} message digest algorithm]")
  done

  local -a cipher_flags=($(openssl enc -list | tail -n +2 ))
  local -a ciphers=()
  for flag in $cipher_flags[@]
  do
    ciphers+=("${flag:1}")
  done

  _arguments \
    '(- *)-help[print help message]' \
    '-inform[CSR input file format]:format:(DER PEM)' \
    '-outform[output format]:format:(DER PEM)' \
    '-cipher[cipher to use]:cipher:(($ciphers))' \
    '-in[input file name]:file:_files' \
    '-sigopt[options of the signature algorithm during sign operations]:options' \
    '-vfyopt[options of the signature algorithm during verify operations]:options' \
    '-passin[password source for private key and certificate input]:source:_openssl_pass_phrase_options' \
    '-passout[password source for the output file]:source:_openssl_pass_phrase_options' \
    '-out[output file name]:file:_files' \
    '-text[print out the certificate request in text form]' \
    '-subject[print out the certificate request subject]' \
    '-pubkey[print out the public key]' \
    '-noout[prevent output of the encoded version of the certificate request]' \
    '-modules[print out the value of the modulus of the public key]' \
    '-verify[verify the self-signed on the request]' \
    '-new[generate a new certificate request]' \
    '-newkey[generate a new private key]:arg' \
    '-pkeyopt[option of public key algorithm]:option' \
    '-key[private key file or URI]:file_or_uri:_files' \
    '-keyform[format of the private key]:format:(DER PEM P12 ENGINE)' \
    '-keyout[output private key file name]:file:_files' \
    '-noenc[create private key it will not be encrypted]' \
    $digest_flags[@] \
    '-config[config file name]:file:_files' \
    '-section[section name]:section' \
    '-subj[subject name for new request or superseded the subject name]:subject' \
    '-x509[output certificate instead of a certificate request]' \
    '-x509v1[request generation of certificates with X.509 version 1]' \
    '-CA["CA" certificate file or URI]:file_or_uri:_files' \
    '-CAkey["CA" private key file or URI]:file_or_uri:_files' \
    '-not_before[start date to be explicitly set]:date'\
    '-not_after[expiry date to be explicitly set]:date'\
    '-days[the number of days from today to certify the certificate for]:days' \
    '-set_serial[serial number to use when outputting a self-signed certificate]:serial' \
    '-copy_extensions[how X.509 extensions in certificate requests should be handled]:type:(none copy copyall)' \
    '-extensions[specify certificate extension section (override value in config file)]:section' \
    '-reqexts[specify request extension section (override value in config file)]:section ' \
    '-addext[add a specific extension to the certificate]:ext' \
    '-precert[add poison extension to the certificate]' \
    '-utf8[interpret field values as UTF8 strings]' \
    '-reqopt[options to customize the printing format]:option:_openssl_text_printing_options' \
    '-newhdr[add the word NEW to the PEM file header and footer lines]' \
    '-batch[non-interactive mode]' \
    '-verbose[print extra details about the operations being performed]' \
    '-quiet[print fewer details about the operations being performed]' \
    '-keygen_engine[engine for key generation operations]:id' \
    '-nameopt[how subject or issuer names are displayed]:option:_openssl_name_display_options' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@]
}

_openssl_rsa() {
  _arguments \
    '(- *)-help[print help message]' \
    '-inform[key input format]:format:(DER PEM P12 ENGINE)' \
    '-outform[key output format]:format:(DER PEM)' \
    '-traditional[use the traditional PKCS#1 format instead of PKCS#8 format]' \
    '-in[input file or URI]:file_or_uri:_files' \
    '-passin[input password source]:source:_openssl_pass_phrase_options' \
    '-passout[output password source]:source:_openssl_pass_phrase_options' \
    '-out[output file name]:file:_files' \
    '-aes128[encrypt the private key with AES128]' \
    '-aes192[encrypt the private key with AES192]' \
    '-aes256[encrypt the private key with AES256]' \
    '-aria128[encrypt the private key with ARIA128]' \
    '-aria192[encrypt the private key with ARIA192]' \
    '-aria256[encrypt the private key with ARIA256]' \
    '-camellia128[encrypt the private key with CAMELLIA128]' \
    '-camellia192[encrypt the private key with CAMELLIA192]' \
    '-camellia256[encrypt the private key with CAMELLIA256]' \
    '-des[encrypt the private key with DES]' \
    '-des3[encrypt the private key with DES3]' \
    '-idea[encrypt the private key with IDEA]' \
    '-text[print out the various public or private key components in plain text]' \
    '-noout[prevent output of the encoded version of the key]' \
    '-module[print out the value of the modules of the key]'\
    '-check[check the consistency of an RSA private key]' \
    '-pubin[read public key instead of private key]' \
    '-pubout[output public key instead of private key]' \
    '-RSAPublicKey_in[read RSA public key instead of private key]' \
    '-RSAPublicKey_out[output RSA public key instead of private key]' \
    '-pvk-strong[enable "Strong" PVK encoding level(default)]' \
    '-pvk-weak[enable "Weak" PVK encoding level]' \
    '-pvk-none[do not enforce PVK encoding]' \
    $openssl_provider_options[@]
}

_openssl_rsautl() {
  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name]:file:_files' \
    '-passin[pass phrase option]:option:_openssl_pass_phrase_options' \
    '-rev[reverse the order of the input]' \
    '-out[output file name]:file:_files' \
    '-inkey[input key file or URI]:file_or_uri:_files' \
    '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
    '-pubin[read public key instead of private key]' \
    '-certin[input is a certificate containing an RSA public key]' \
    '-sign[sign the input data and output the signed result]' \
    '-verify[verify the input data and output the recovered data]' \
    '-encrypt[encrypt the input data using an RSA public key]' \
    '-decrypt[decrypt the input data using an RSA private key]' \
    '-pkcs[use PKCS#1 for padding]' \
    '-oaep[use OAEP for padding]' \
    '-x931[use ANSI X9.31 for padding]' \
    '-raw[do not use padding]' \
    '-hexdump[hex dump the output data]' \
    '-asn1parse[parse the ASN.1 output data]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@]
}

_openssl_s_client() {
  local tls_start_protocols=(smtp pop3 imap ftp xmpp xmpp-server irc postgres mysql lmtp nntp sieve ldap)

  _arguments \
   '(- *)-help[print help message]' \
   '-ssl_config[section of the configuration file to configure the SSL_CTX object]:section' \
    '-connect[host and optional port to connect to]:host_port' \
    '-host[host to connect to]:host' \
    '-port[port to connect to]:port' \
    '-bind[host address and port to bind as the source for the connection]:host_port' \
    '-proxy[proxy host and port]:host_port' \
    '-proxy_user[proxy user for basic(base64) authenticate]' \
    '-proxy_pass[proxy password source]:option:_openssl_pass_phrase_options' \
    '-unix[connect over the specified Unix-domain socket]:path:_files' \
    '(-4 -6)-4[use IPv4 only]' \
    '(-4 -6)-6[use IPv6 only]' \
    '-quic[connect using the QUIC protocol]' \
    '-servername[set the TLS SNI extension in the ClientHello to the given value]:name' \
    '-noservername[suppress sending of the SNI extension in the ClientHello message]' \
    '-cert[client certificate path]:file:_files' \
    '-certform[client certificate file format]:format:(DER PEM P12)' \
    '-cert_chain[file or URI of untrusted certificates to build the certificate chain]:file_or_uri:_files' \
    '-build_chain[whether the application build build the client certificate chain]' \
    "-CRL[CRL file to use to check the server's certificate]" \
    '-CRLform[CRL file format]:format:(DER PEM)' \
    '-crl_download[download CRL from distribution points in the certificate]' \
    '-key[client private key to use(file or URI)]:file_or_uri:_files' \
    '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
    '-pass[private key and certificate file password source]:option:_openssl_pass_phrase_options' \
    '-verify[verify depth]:depth' \
    '-verify_return_error[returns verification error instead of continuing]' \
    '-verify_quiet[limit verify output to only errors]' \
    '-verifyCAfile[file in PEM format containing trusted certificates to verify]:file:_files' \
    '-verifyCApath[directory containing trusted certificates to verify]:dir:_files -/' \
    '-verifyCAstore[URI of a tstore containing trusted certificatesto verify]:uri:_urls' \
    '-chainCAfile[file in PEM format containing certificates to build client certificate chain]:file:_files' \
    '-chainCApath[directory containing trusted certificates for building client certificate chain]:dir:_files -/' \
    '-chainCAstore[URI of a store containing trusted certificate to build client certificate chain]:uri:_urls' \
    '-requestCAfile[file containing a list of certificates to be sent to the server]:file:_files' \
    '-dane_tlsa_domain[enable DANE TLSA authentication and specify the TLSA base domain]:domain' \
    '-dane_tlsa_rrdata[use one or more times to specify the RRDATA fields of the DANE TLSA RRset]:rrdata' \
    '-dane_ee_no_namechecks[disable server name checks when authenticating via DANE-EE TLSA records]' \
    '-reconnect[reconnect to the same server 5 time using the same sess_id ID]' \
    '-showcerts[display the server certificate list as sent by the server]' \
    '-prexit[print session information when the program exits]' \
    '-no-interactive[run the client in a non-interactive mode]' \
    '-state[print out the SSL session states]' \
    '-debug[print extensive debugging information including a hex dump of all traffic]' \
    '-nocommands[do not use interactive command letters]' \
    '-adv[use advanced command mode]' \
    '-security_debug[enable security debug messages]' \
    '-security_debug_verbose[output more security debug output]' \
    '-msg[show protocol messages]' \
    '-timeout[enable send/receive timeout on DTLS connections]' \
    '-mtu[set MTU of the link layer]:size' \
    '-no_ems[disable Extended master secret negotiation]' \
    '-keymatexport[export keying materials using the specified label]:label' \
    '-keymatexportlen[export the specified number of bytes of keying material(default 20)]:len' \
    '-trace[show verbose trace output of protocol messages]' \
    '-msgfile[file to send output of -msg or -trace to]:file:_files' \
    '-nbio_test[test nonblocking I/O]' \
    '-nbio[turn on nonblocking I/O]' \
    '-crlf[translate a line feed from the terminal into CF+LF]' \
    '-ign_eof[inhibit shutting down the connection when end of file is reached in the input]' \
    '-quiet[inhibit printing of session and certificate information]' \
    '-no_ign_eof[shut down the connection when end of file is reached in the input]' \
    '-psk_identity[PSK identity when using a PSK cipher suite]:identity' \
    '-psk[PSK key when using a PSK cipher suite]:key' \
    '-psk_session[use the pem encoded SSL_SESSION data stored in file as the basic of a PSK]:file:_files' \
    '-sctp[use SCTP for the transport protocol instead of UDO in DTLS]' \
    '-sctp_label_bug[use the incorrect behaviour of older OpenSSL implementations for DTLS/SCTP]' \
    '-fallback_scsv[send TLS_FALLBACK_SCSV in the ClientHello]' \
    '-async[switch on asynchronous mode]' \
    '-maxfraglen[enable Maximum Fragment Length Negotiation]:len:(512 1024 2048 4096)' \
    '-max_send_frag[maximum size of data fragment to send]:size' \
    '-split_send_frag[size used to split data for encrypt pipelines]:size' \
    '-max_pipelines[maximum number of encrypt/decrypt pipelines]:number' \
    '-read_buf[default read buffer size for connections]:size' \
    '-ignore_unexpected_eof[enable the peer does not need to send the close_notify alert]' \
    '-no_tx_cert_comp[disable support for sending TLSv1.3 compressed certificates]' \
    '-no_rx_cert_comp[disable support for receiving TLSv1.3 compressed certificate]' \
    '-brief[only provide a brief summary of connections parameters]' \
    '-starttls[send the protocol-specific message to switch to TLS for communication]:protocol:(($tls_start_protocols))' \
    '-xmpphost[host for the "to" attribute of the stream element]:host' \
    '-name[hostname information for various protocols]:hostname' \
    '-tlsextdebug[print out a hex dump of any TLS extensions received from the server]' \
    '-sess_out[output SSL session to file]:file:_files' \
    '-sess_in[load SSL session from this file]:file:_files' \
    '-serverinfo[list of comma-separated TLS Extension Types]:types' \
    '-status[send a certificate status request to the server(OCSP stapling)]' \
    '-alpn[enable Application-Layer Protocol Negotiation]:protocols' \
    '-nextprotoneg[enable Next Protocol Negotiation extension]:protocols' \
    '(-ct -noct)-ct[enable Certificate Transparency]' \
    '(-ct -noct)-noct[disable Certificate Transparency]' \
    '-ctlogfile[file containing a list of known Certificate Transparency]' \
    '-keylogfile[keylog file for appending TLS secrets]:file:_files' \
    '-early_data[file to read the content and attempt to send it as early data]:file:_files' \
    '-enable_pha[send the Post-Handshake Authentication extension]' \
    '-use_srtp[offer SRTP key management]:value' \
    '-ktls[enable kernel TLS for sending and receiving]' \
    '-tfo[enable creation of connections via TCP fast open]' \
    $openssl_tls_flags[@] \
    $openssl_dtls_flags[@] \
    '-nameopt[how the subject or issuer names are displayed]:option:_openssl_name_display_options' \
    $openssl_extended_verification_flags[@] \
    $openssl_trusted_certificate_options[@] \
    $openssl_supported_commands_flags[@] \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-ssl_client_engine[specified engine to be used for client certificate operations]:id' \
    $openssl_verification_options[@] \
    '-enable_server_rpk[enable support for receiving raw public keys from the server]' \
    '-enable_client_rpk[enable support for sending raw public keys to the server]' \
    '*::host_port'
}

_openssl_s_server() {
  _arguments  \
   '(- *)-help[print help message]' \
   '-port[TCP port to listen on for connections(default: 4433)]:port' \
   '-accept[optional TCP host and port to listen on for connections(default: *:4433)]:host_port' \
   '-unix[Unix domain socket path]:path:_files' \
   '(-4 -6)-4[use IPv4 only]' \
   '(-4 -6)-6[use IPv6 only]' \
   '-unlink[for -unix, unlink any existing socket first]' \
   '-context[SSL context ID]:id' \
   '(-verify -Verify)'{-verify,-Verify}'[verify depth]:depth' \
   '-cert[certificate file]:file:_files' \
   '-cert2[certificate file to use for servername(default: server2.pem)]:file:_files' \
   '-certform[server certificate file format]:format:(DER PEM P12)' \
   '-cert_chain[file or URI of untrusted certificates to build the certificate chain]:file_or_uri:_files' \
   '-build_chain[application should build the server certificate chain]' \
   '-serverinfo[file containing one or more blocks of PEM data]:file:_files' \
   '-key[private key file or URI]:file_or_uri:_files' \
   '-key2[private key file or URI to use for servername]:file_or_uri:_files' \
   '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
   '-pass[private key and certificate file password source]:source:_openssl_pass_phrase_options' \
   '-dcert[additional certificate file]:file:_files' \
   '-dkey[additional private key file or URI]:file_or_uri:_files' \
   '-dcert_chain[file or URI of untrusted certificates to build the server certificate chain]:file_or_uri:_files' \
   '-dcertform[format of the additional certificate file]:format:(DER PEM P12)' \
   '-dkeyform[format of the additional private key]:format:(DER PEM P12 ENGINE)' \
   '-dpass[passphrase for the additional private key and certificate]:pass:_openssl_pass_phrase_options' \
   '-nbio_test[test non blocking I/O]' \
   '-crlf[translate a line feed from the terminal into CR+LF]' \
   '-debug[print extensive debugging information including a hex dump of all traffic]' \
   '-security_debug[print output from SSL/TLS security framework]' \
   '-security_debug_verbose[print more output from SSL/TLS security framework]' \
   '-msg[show all protocol messages with hex dump]' \
   '-msgfile[file to send output of -msg or -trace to]:file:_files' \
   '-state[print the SSL session states]' \
   '-CRL[CRL file]:file:_files' \
   '-CRLform[CRL file format]:format:(DER PEM)' \
   '-crl_download[download CRLs from distribution points]' \
   '-verifyCAfile[file in PEM format CA containing trusted certificates to verify client certificates]:file:_files' \
   '-verifyCApath[directory containing trusted certificates to verify client certificates]:dir:_files -/' \
   '-verifyCAstore[URI of a store containing trusted certificates to verify client certificates]:uri:_urls' \
   '-chainCAfile[file in PEM format containing trusted certificates to build the server certificate chain]:file:_files' \
   '-chainCApath[directory containing trusted certificates for building server certificate chain]:dir:_files -/' \
   '-chainCAstore[URI of a store containing trusted certificates for building server certificate chain]:uri:_urls' \
   '-nocert[no certificate is used]' \
   '-quiet[inhibit printing of session and certificate information]' \
   '-no_resume_ephemeral[disable caching and tickets if ephemeral (EC)DH is used]' \
   '-tlsextdebug[print a hex dump of any TLS extensions received from the server]' \
   '-www[send a status message back to the client when it connects]' \
   '(-WWW -HTTP)'{-WWW,-HTTP}'[emulate a simple web server]' \
   '-http_server_binmode[acting as web-server open files in binary mode]' \
   '-no_ca_names[disable TLS Extension CA Names]' \
   '-ignore_unexpected_eof[peer does not need to send the close_notify alert]' \
   '-servername[servername for HostName TLS extension]' \
   '-servername_fatal[send fatal alert on servername mismatch]' \
   '-id_prefix[generate SSL/TLS session IDs prefixed by this ID]:id' \
   '-keymatexport[export keying material using label]:label' \
   '-keymatexportlen[export the given number of bytes of keying material(default: 20)]:length' \
   '-no_cache[disable session cache]' \
   '-ext_cache[disable internal cache]' \
   '-verify_return_error[close the connection when verification errors occur]' \
   '-verify_quiet[no verify output except verify errors]' \
   '(-no_ign_eof -ign_eof)-ign_eof[ignore input EOF]' \
   '(-no_ign_eof -ign_eof)-no_ign_eof[do not ignore input EOF]' \
   '-no_ems[disable Extended master secret negotiation]' \
   '-status[enable certificate status request support]' \
   '-status_verbose[enable certificate status request support and verbose output of OCSP response]' \
   '-status_timeout[set the timeout for OCSP reponse to the given seconds]:seconds' \
   '-proxy[HTTP(S) proxy server]:proxy' \
   '-no_proxy[list of IP addresses and/or DNS names not to use an HTTP(S) proxy for]:addresses' \
   '-status_url[set a fallback responder URL]:url:_urls' \
   '-status_file[status file]:file:_files' \
   '-ssl_config[configure SSL_CTX using the given configure value]:config' \
   '-trace[show verbose trace output of protocol messages]' \
   '-brief[provide a brief summary of connection parameters]' \
   '-rev[simple echo server that sends back received text reserved]' \
   '-async[switch on asynchronous mode]' \
   '-max_send_frag[maximum size of data fragment to send]:size' \
   '-split_send_frag[size used to split data for encrypt pipelines]:size' \
   '-max_pipelines[maximum number of encrypt/decrypt pipelines]:number' \
   '-naccept[server will exit after receiving the specified number of connections(default: unlimited)]:number' \
   '-read_buf[default read buffer size for connections]:size' \
   '-no_tx_cert_comp[disable support for sending TLSv1.3 compressed certificates]' \
   '-no_rx_cert_comp[disable support for receiving TLSv1.3 compressed certificates]' \
   '-no_comp[disable negotiation of TLS compression]' \
   '-num_tickets[control the number of tickets that will be sent to the client after a full handshake in TLSv1.3]' \
   '-dhparam[DH parameter file to use]:file:_files' \
   '-nbio[turn on non blocking I/O]' \
   '-timeout[enable timeout]' \
   '-mtu[set link-layer MTU]:size' \
   '-psk_identity[PSK identify when using a PSK cipher suite]:id' \
   '-psk_hint[PSK identity hint when using a PSK cipher suite]:hint' \
   '-psk[PSK key when using a PSK cipher suite]:key' \
   '-psk_session[file contains pem encoded SSL_SESSION data]:file:_files' \
   '-srpvfile[verifier file for SRP]:file:_files' \
   '-listen[listen on a UDP port for incoming connections]' \
   '-sctp[use SCTP for the transport protocol instead of UDP in DTLS]' \
   '-sctp_label_bug[allow communication with older broken implementations]' \
   '-use_srtp[offer SRTP key management with a colon-separated profile list]:list' \
   '-no_dhe[no DH parameters will be loaded]' \
   '-alpn[enable the Application-Layer Protocol Negotiation extension]:protocol' \
   '-nextprotoneg[enable the Next Protocol Negotiation extension]:protocol' \
   '-ktls[enable kernel TLS for sending and receiving]' \
   '-sendfile[SSL_sendfile will be used instead of BIO_write to send response]' \
   '-zerocopy_sendfile[SSL_sendfile will use the zerocopy TX mode]' \
   '-keylogfile[append TLS secrets to the specified keylog file]:file:_files' \
   '-max_early_data[change the default maximum early data bytes for new sessions and incoming early data]:size' \
   '-recv_max_early_data[hard limit on the maximum number of early data bytes that will be accepted]:bytes' \
   '-early_data[accept early data where possible]' \
   '-stateless[require TLSv1.3 cookies]' \
   '(-anti_replay -no_anti_replay)-anti_replay[switch replay protection on]' \
   '(-anti_replay -no_anti_replay)-no_anti_replay[switch replay protection off]' \
   '-tfo[enable acceptance of TCP fast Open connections]' \
   '-cert_comp[pre-compresses certificates that will be sent during the handshake]' \
   '-nameopt[how the subject or issuer names are displayed]:how:_openssl_name_display_options' \
   $openssl_tls_flags[@] \
   $openssl_dtls_flags[@] \
   $openssl_supported_commands_flags[@] \
   $openssl_extended_verification_flags[@] \
   $openssl_trusted_certificate_options[@] \
   $openssl_random_state_options[@] \
   $openssl_provider_options[@] \
   $openssl_verification_options[@] \
   '-enable_server_rpk[enable support for sending raw public keys to the client]' \
   '-enable_client_rpk[enable support for receiving raw public keys from the client]'
}

_openssl_s_time() {
  _arguments \
    '(- *)-help[print help message]' \
    '-connect[host and optional port to connect to]:host_port' \
    '-www[page to GET from the server. "/" gets the index.html page]:page' \
    '-cert[certificate to use]:certificate' \
    '-key[private key to use]:key:_files' \
    '-verify[verify depth to use]:depth' \
    '-new[performs the timing test using a new session ID for each connection]' \
    '-reuse[performs the timing test using the same session ID]' \
    '-bugs[enable various workaround for known SSL and TLS implementations]' \
    '-cipher[allow TLSv1.2 and cipher list sent by the client to be modified]:ciperlist:_openssl_list_ciphers' \
    '-ciphersuites[allow the TLSv1.3 ciphersuites sent by the client to be modified]:val' \
    '-time[specify how long seconds this command should establish connections]:seconds' \
    '-nameopt[specify how the subject or issuer names are displayed]:option:_openssl_nameopts' \
    $openssl_trusted_certificate_options[@] \
    $openssl_provider_options[@] \
    $openssl_tls_flags[@]
}

_openssl_sess_id() {
  _arguments \
    '(- *)-help[print help message]' \
    '-context[set the session ID context]:id' \
    '-in[input file(default stdin)]:file:_files' \
    '-inform[input format(default PEM)]:format:(DER PEM)' \
    '-out[output file(default stdout)]:file:_files' \
    '-outform[output format(default PEM)]:format:(PEM DER NSS)' \
    '-text[print ssl session id details]' \
    '-cert[output certificate]' \
    '-noout[do not output the encoded session info]'
}

_openssl_smime() {
  local -a ciphers=($(openssl enc -list | tail -n +2 ))
  local -a cipher_flags=()
  for cipher in $ciphers[@]
  do
    cipher_flags+=("($ciphers)${cipher}[use ${cipher:1}]")
  done

  _arguments \
    '(- *)-help[print help message]' \
    '-encrypt[encrypt message]' \
    '-decrypt[decrypt message]' \
    '-sign[sign message using the supplied certificate and private key]' \
    '-resign[resign a message]' \
    '-verify[verify signed message]' \
    '-pk7out[write out a PEM encoded PKCS#7 structure]' \
    '-in[input message file]:file:_files' \
    '-out[output file name]:file:_files' \
    '-inform[input format]:format:(DER PEM SMIME)' \
    '-outform[output format]:format(DER PEM SMIME)' \
    '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
    '(-stream -indef)'{-stream,-indef}'[enable streaming I/O for encoding operations]' \
    '-noindef[disable streaming I/O]' \
    '-content[file containing the detached content]:file:_files' \
    '-text[add plain text MIME headers to the supplied message]' \
    '-md[digest algorithm to use when signing or resigning]:digest:(sha256 sha1 md5' \
    $cipher_flags[@] \
    '-nointern[use only the certificate in the -certificate]' \
    '-noverify[do not verify the signers certificate of a signed message]' \
    '-nochain[do not do chain verifier of signers certificates]' \
    '-nosigs[do not try to verify the signatures on the message]' \
    '-nocerts[reduce the size of the signed message]' \
    '-noattr[do not include attributes in the mssage]' \
    '-nodetach[use opaque signing]' \
    '-nosmimecap[do not include the SMIMECapabilities attribute]' \
    '-binary[do not convert message to "canonical" format]' \
    '-crlfeol[use CRLF instead of LF as end of line in output file]' \
    '-certfile[additional certificate file]:file:_files' \
    '*-signer[signing certificate]:file:_files' \
    '-recip[recipients certificate when decrypting a message]:file:_files' \
    '-inkey[private key file or URI for signing or decrypting]:file_or_uri:_files' \
    '-passin[private key password source]:source:_openssl_pass_phrase_options' \
    '-to["To" mail header]:addr' \
    '-from["From" mail header]:addr' \
    '-subject["Subject" mail header]:subject' \
    $openssl_verification_options[@] \
    $openssl_trusted_certificate_options[@]\
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-config[config file]:file:_files' \
    '*::recip_rert:_files'
}

_openssl_speed() {
  # NOTE extract algorithms from speed.c and check if 'openssl speed -seconds 1 $alg' succeed
  local -a speed_algorithms=(
    md2 mdc2 md4 md5 hmac sha1 sha256 sha512 whirlpool ripemd rmd160
    ripemd160 rc4 des-cbc des-ede3 aes-128-cbc aes-192-cbc aes-256-cbc
    camellia-128-cbc camellia-192-cbc camellia-256-cbc rc2-cbc rc2 rc5-cbc
    rc5 idea-cbc idea seed-cbc seed bf-cbc blowfish bf cast-cbc cast cast5
    ghash rand kmac128 kmac256 dsa1024 dsa2048 rsa512 rsa1024 rsa2048
    rsa3072 rsa4096 rsa7680 rsa15360 ffdh2048 ffdh3072 ffdh4096 ffdh6144
    ffdh8192 ecdsap160 ecdsap192 ecdsap224 ecdsap256 ecdsap384 ecdsap521
    ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571 ecdsab163 ecdsab233
    ecdsab283 ecdsab409 ecdsab571 ecdsabrp256r1 ecdsabrp256t1
    ecdsabrp384r1 ecdsabrp384t1 ecdsabrp512r1 ecdsabrp512t1 ecdhp160
    ecdhp192 ecdhp224 ecdhp256 ecdhp384 ecdhp521 ecdhk163 ecdhk233
    ecdhk283 ecdhk409 ecdhk571 ecdhb163 ecdhb233 ecdhb283 ecdhb409
    ecdhb571 ecdhbrp256r1 ecdhbrp256t1 ecdhbrp384r1 ecdhbrp384t1
    ecdhbrp512r1 ecdhbrp512t1 ecdhx25519 ecdhx448 curveSM2
  )

  _arguments \
    '(- *)-help[print help message]' \
    '-config[configuration file]:file:_files' \
    '-elapsed[use wall-clock time instead of CPU user time as divisor]' \
    '-evp[use specified cipher or message digest algorithm via the EVP interface]:alg: _alternative "ciphers\:cipher\:_openssl_digests" "digests\:digest\:_openssl_cipher_algorithms"' \
    '-multi[run multiple operations in parallel]:number' \
    '-async_jobs[enable async mode and start specified number of jobs]:number' \
    '-misalign[misalign the buffers by the specified number of bytes]:number' \
    '-hmac[time the HMAC algorithm using the given message digest]:digest:_openssl_digests' \
    '-cmac[time the CMAC algorithm using the given cipher]:cipher:_openssl_cipher_algorithms' \
    '-decrypt[time the decryption instead of encryption]' \
    '-mb[enable multi-block mode on EVP-named cipher]' \
    '-aead[benchmark EVP-named AEAD cipher in TLS-like sequence]' \
    '-kem-algorithms[benchmark KEM algorithms]' \
    '-signature-algorithms[benchmark signature algorithms]' \
    '-primes[generate n prime RSA key and use it to run the benchmarks]:number' \
    '-seconds[run benchmarks for the given seconds]:number' \
    '-bytes[run benchmarks on num-byte buffers]:bytes' \
    '-mr[produce the summary in a machine-readable format]' \
    '-mlock[lock memory into RAM for more determining measurements]' \
    '-testmode[run the speed command in testmode]' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '*::alg:(($speed_algorithms))'
}

_openssl_spkac() {
  _arguments \
    '(- *)-help[print help message]' \
    '-in[input file name]:file:_files' \
    '-out[output file name]:file:_files' \
    '-digest[digest to sign a created SPKAC file]:digest:_openssl_digests' \
    '-key[private key file or URI to create an SPKAC file]:file_or_uri:_files' \
    '-keyform[key format]:format:(DER PEM P12 ENGINE)' \
    '-passin[input file password source]:option:_openssl_pass_phrase_options' \
    '-challenge[challenge string]:string' \
    '-spkac[alternative name form the variable containing the SPKAC(default "SPKAC")]:name' \
    '-spksect[allow an alternative name form the section containing the SPKAC]:section' \
    '-noout[do not output the text version of the SPKAC]' \
    '-pubkey[output the public key of an SPKAC]' \
    '-verify[verify the digital signature on the supplied SPKAC]' \
    $openssl_provider_options[@]
}

_openssl_srp() {
  _arguments \
    '(- *)-help[print help message]' \
    '-verbose[generate verbose output while processing]' \
    '(-add -modify -delete -list)-add[add a user and SRP verifier]' \
    '(-add -modify -delete -list)-modify[modify the SRP verifier of an existing user]' \
    '(-add -modify -delete -list)-delete[delete user from verifier file]' \
    '(- *)-list[list users]' \
    '-name[particular SRP definition to use]:name' \
    '-srpvfile[srp verifier file name]:file:_files' \
    '-gn[specify the "g" and "N" value]:g_and_N' \
    '-userinfo[additional information to add when adding or modifying a user]:info' \
    '-passin[password source for input file]:option:_openssl_pass_phrase_options' \
    '-passout[password source for output file]:option:_openssl_pass_phrase_options' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@] \
    '-config[config file]:file:_files' \
    '*::user'
}

_openssl_storeutl() {
  _arguments \
    '(- *)-help[print help message]' \
    '-out[output file name]:file:_files' \
    '-noout[prevent output of the PEM data]' \
    '-passin[key password source]:option:_openssl_pass_phrase_options' \
    '-text[print out the objects in text form]' \
    '-r[fetch objects recursively when possible]'\
    '-certs[only select the certificates from the given URI]' \
    '-keys[only select the keys from the given URI]' \
    '-crls[only select the CRLs from the given URI]' \
    '-subject[search for an object having the subject name arg]:arg' \
    '-issuer[search for an object having the given issuer name]:name' \
    '-serial[search for an object having the given serial number]:serial_number' \
    '-alias[search for an object having the given alias]:alias' \
    '-fingerprint[search for an object having the given fingerprint]:fingerprint' \
    '-digest[digest that was used to compute the fingerprint given with -fingerprint]' \
    $openssl_provider_options[@] \
    '*:uri:_urls'
}

_openssl_ts() {
  if [[ CURRENT -eq 2 ]]; then
    _arguments \
      '(- *)-help[print help message]' \
      '-query[generate a TS query]' \
      '-reply[generate a TS reply]' \
      '-verify[verify a TS response]'
  else
    local -a digests=($(openssl dgst -list | tail -n +2))
    local -a digest_flags=()
    for digest in $digests[@]
    do
      digest_flags+=("${digest}[use ${digest:1} message digest algorithm]")
    done

    case $words[2] in
      (-query)
        _arguments \
          '-config[configuration file]:file:_files' \
          '-data[data file for creating timestamp request]:file:_files' \
          '-digest[message imprint in a hexadecimal format]:digest' \
          $digest_flags[@] \
          '-tspolicy[policy that the client expects the TSA for creating the timestamp token]:oid' \
          '-no_nonce[no nonce instead of 64bit long pseudo-random nonce]' \
          '-cert[TSA is expected to include its signing certificates in the response]' \
          '-in[previously created timestamp request]:file:_files' \
          '-out[output file name]:file:_files' \
          '-text[output human-readable text format instead of DER]' \
          $openssl_random_state_options[@]
        ;;
      (-reply)
        _arguments \
          '-config[configuration file]:file:_files' \
          '-section[name of the config file section for the response generation]:section' \
          '-queryfile[file containing a DER encoded timestamp request]:file:_files' \
          '-passin[password source for the private key of the TSA]:source:_openssl_pass_phrase_options' \
          '-signer[signer certificate of the TSA in PEM format]:file:_files' \
          '-inkey[signer private key file or URI of the TSA in PEM format]:file_or_uri:_files' \
          $digest_flags[@] \
          '-chain[certificate chain]:file:_files' \
          '-tspolicy[policy to use for the response]:oid' \
          '-in[previously created timestamp response or timestamp token]:file:_files' \
          '-token_in[input is a DER encoded timestamp token instead of a timestamp response]' \
          '-out[output file name to write the response]:file:_files' \
          '-token_out[output is a timestamp token instead of timestamp response]' \
          '-text[output human-readable text format instead of DER]' \
          $openssl_provider_options[@]
        ;;
      (-verify)
        _arguments \
          '-data[file to hash to be verified against response or token]:file_to_hash:_files' \
          '-digest[message digest to be verified against reponse or token]:bytes' \
          '-queryfile[original timestamp request file in DER format]:file:_files' \
          '-in[timestamp response file in DER format]:file:_files' \
          '-token_in[input is a DER encoded timestamp token instead of a timestamp response]' \
          '-untrusted[set of additional untrusted certificates files or URIs]:file_or_uri:_files' \
          $openssl_trusted_certificate_options[@] \
          $openssl_verification_options[@]
        ;;
    esac
  fi
}

_openssl_verify() {
  _arguments -S  \
    '(- *)-help[print help message]' \
    '-CRLfile[file or URL should contains one or more CRLs in PEM or DER format]:file_or_uri:_files' \
    '-crl_download[attempt to download CRL information for certificates via their CDP entries]' \
    '-show_chain[display information about the certificate chain that has been built]' \
    '-verbose[print extra information about the operations being performed]' \
    '-trusted[file or URI of trusted certificates]:file_or_uri:_files' \
    '-untrusted[file or URI of untrusted certificates to use for chain building]:file_or_uri:_files' \
    '-vfyopt[pass options to the signature algorithms during verify operations]:options' \
    '-nameopt[specify how the subject or issuer names are displayed]:nameopt:_openssl_nameopts' \
    $openssl_trusted_certificate_options[@] \
    $openssl_verification_options[@] \
    $openssl_provider_options[@] \
    '*::certificate:_files'
}

_openssl_version() {
  _arguments \
    '(- *)-help[print help message]' \
    '-a[all information]' \
    '-v[current OpenSSL version]' \
    '-b[date the current version of OpenSSL was built]' \
    '-o[option information, options set when the library was built]' \
    '-f[compilation flags]' \
    '-p[platform setting]' \
    '-d[OPENSSLDIR setting]' \
    '-e[ENGINESDIR settings]' \
    '-m[MODULESDIR settings]' \
    '-r[random number generator source settings]' \
    '-c[OpenSSL CPU settings info]' \
    '-w[OPENSSL OSSL_WINCTX build time variable]'
}

_openssl_x509() {
  local -a digests=($(openssl dgst -list | tail -n +2))
  local -a digest_flags=()
  for digest in $digests[@]
  do
    digest_flags+=("${digest}[use ${digest:1} message digest algorithm]")
  done

  _arguments \
    '(- *)-help[print help message]' \
    '(-in -new)-in[input file or URI for reading a certificate request]:file_or_uri:_files' \
    '-passin[key and certificate file password source]:source:_openssl_pass_phrase_options' \
    '(-in -new)-new[generate a certificate from scratch]' \
    '-x509toreq[output a PKCS#10 certificate request]' \
    '-req[expect a PKCS#10 certificate request]' \
    '-copy_extensions[how to handle X.509 extensions when converting from a certificate to a request]:how:(none copy copyall)' \
    '-inform[input file format]:format:(DER PEM)' \
    '-vfyopt[options of the signature algorithm during verify operations]:option' \
    '(-key -signkey)'{-key,-signkey}'[private key file or URI for a new certificate or certificate request]:file_or_uri:_files' \
    '-keyform[key input format]:format:(DER PEM P12 ENGINE)' \
    '-out[output file name]:file:_files' \
    '-outform[output format]:format:(DER PEM)' \
    '-nocert[do not output a certificate]' \
    '-noout[prevent output except for printing as requested]' \
    '-dataopt[data output format(default: rfc_822)]:format:(rfc_822 iso_8601)' \
    '-text[print out the certificate in text form]' \
    '-certopt[option to customize the print format used with -text]:option:_openssl_text_printing_options' \
    '-fingerprint[calculate and print the digest of the DER encoded version of the entire certificate]' \
    '-alias[print the certificate "alias"(nickname) if any]' \
    '-serial[print the certificate serial number]' \
    '-startdate[print out the start date of the certificate]' \
    '-enddate[print out the expiry date of the certificate]' \
    '-dates[print out the start and expiry dates of a certificate]' \
    '-subject[print the subject name]' \
    '-issuer[print the issuer name]' \
    '-nameopt[how the subject or issuer names are displayed]:option:_openssl_nameopts' \
    '-email[print the email address(es) if any]' \
    '(-hash -subject_hash)'{-hash,-subject_hash}'[print the "hash" of the certificate subject name]' \
    '-subject_hash_old[print the "hash" of the certificate subject name using the older algorithm]' \
    '-issuer_hash[print the "hash" of the certificate issuer name]' \
    '-issuer_hash_old[print the "hash" of the certificate issuer name using the older algorithm]' \
    '-ext[print out the certificate extensions in text form]:extensions:_openssl_certificate_extensions' \
    '-ocspid[print the OCSP hash values for the subject name and public key]' \
    '-ocsp_uri[print the OCSP responder address(es) if any]' \
    '-purpose[perform tests on the certificate extensions and output the result]' \
    "-pubkey[print the certificate's SubjectPublicKeyInfo block in PEM format]" \
    '-modulus[print out the value of the modulus of the public key contained in the certificate]' \
    '-checkend[check if the certificate expires within the given seconds]:seconds' \
    '-checkhost[check that the certificate matches the specified host]:host' \
    '-checkemail[check that the certificate matches the specified email address]:email' \
    '-checkip[check that the certificate matches the specified IP address]:ip' \
    '-set_serial[serial number to use]:serial_number' \
    '-next_serial[serial to be one more than the number in the certificate]' \
    '-not_before[start date to be explicitly set]:date' \
    '-not_after[expiry date to be explicitly set]:date' \
    '-days[the number of days from today until a newly generated certificate expires]:days' \
    '-preserve_dates[preserve "notBefore" and "notAfter" dates of any input certificate]' \
    '-set_issuer[issuer name for certicate created]:issuer' \
    '(-set_subject -subj)'{-set_subject,-subj}'[subject name for certicate created]:subject' \
    '-force_pubkey[public key file to be set in certicate created]:file:_files' \
    '-clrext[prevents taking over any extensions from the source]' \
    '-extfile[configuration file containing certificate and request X.509 extensions to add]:file:_files' \
    '-extensions[section in the extfile to add X.509 extensions form]:section' \
    '-sigopt[options to the signature algorithm during sign operations]:options' \
    '-badsig[currupt the signature before writing it]' \
    $digest_flags[@] \
    '-CA["CA" certificate file or URI]:file_or_uri:_files' \
    '-CAform[format for the CA certificate]:format:(DER PEM P12)' \
    '-CAkey[CA private key file or URI to sign a certificate with]:file_or_uri:_files' \
    '-CAkeyform[format for the CA key]:format:(DER PEM P12 ENGINE)' \
    '-CAserial[CA serial number file to use]:file:_files' \
    '-CAcreateserial[create CA serial number file if it does not exist]' \
    '-trustout[mark any certificate PEM output as <trusted> certificate rather than ordinary]' \
    '-setalias[set the "alias" of the certificate]:alias' \
    '-clrtrust[clear all the permitted or trusted uses of the certificate]' \
    '-addtrust[add a trusted certificate use]:name:(clientAuth serverAuth emailProtection anyExtendedKeyUsage)' \
    '-clrreject[clear all the prohibited or rejected use of the certificate]' \
    '-addreject[add a prohibited trust anchor purpose]:arg:(clientAuth serverAuth emailProtection anyExtendedKeyUsage)' \
    $openssl_random_state_options[@] \
    $openssl_provider_options[@]
}

#
# Utilities
#

_openssl_certificate_extensions() {
  # See x509v3_config document

  local -a extensions=(
    basicConstraints keyUsage extendedKeyUsage subjectKeyIdentifier authorityKeyIdentifier
    subjectAltName issuerAltName authorityInfoAccess crlDistributionPoints
    issuingDistributionPoint certificatePolicies policyConstraints
    inhibitAnyPolicy nameConstraints noCheck tlsfeature
  )

  _values -s , extensions $extensions
}

_openssl_digests() {
  # openssl list -digest-commands is deprecated, use another command instead
  local -a digest_flags=($(openssl dgst -list | tail -n +2))
  local -a digests=()

  for flag in $digest_flags[@]
  do
    digests+=(${flag:1})
  done

  _values 'digests' ${digests}
}

_openssl_cipher_algorithms() {
  local -a encrypt_flags=($(openssl enc -list | tail -n +2))
  local -a encrypts=()

  for flag in $encrypt_flags[@]
  do
    encrypts+=(${flag:1})
  done

  _values 'encrypts' ${encrypts}
}

_openssl_groups() {
  local -a groups=(P-256 P-384 P-521 X25519 X448 ffdhe2048 ffdhe3072 ffdhe4096 ffdhe6144 ffdhe8192)
  _values -s ':' groups $groups
}

_openssl_list_ciphers() {
  # openssl ciphers
  local ciphers
  # add cipher suites
  ciphers=(${(@s/:/)"$(_call_program ciphers openssl ciphers)"})
  # add static cipher strings
  ciphers=(${ciphers} \
    'DEFAULT[the default cipher list]' \
    'COMPLEMENTOFDEFAULT[the ciphers included in ALL but not enabled by default]' \
    'ALL[all cipher suites except the eNULL ciphers]' \
    'COMPLEMENTOFALL[the cipher suites not enabled by ALL]' \
    'HIGH["high" encryption cipher suites]' \
    'MEDIUM["medium" encryption cipher suites]' \
    'LOW["low" encryption cipher suites]' \
    {EXP,EXPORT}'[export encryption algorithms]' \
    'EXPORT40[40 bit export encryption algorithms]' \
    'EXPORT56[56 bit export encryption algorithms]' \
    {eNULL,NULL}'[ciphers offering no encryption]' \
    'aNULL[ciphers offering no authentication]' \
    {kRSA,RSA}'[cipher suites using RSA key exchange]' \
    'kDHr[cipher suites using DH key agreement signed by CAs with RSA keys]' \
    'kDHd[cipher suites using DH key agreement signed by CAs with DSS keys]' \
    'kDH[cipher suites using DH key agreement]' \
    {kDHE,kEDH}'[cipher suites using ephemeral DH key agreement, including anonymous cipher suites]' \
    {DHE,EDH}'[cipher suites using authenticated ephemeral DH key agreement]' \
    'ADH[anonymous DH cipher suites, not including anonymous ECDH ciphers]' \
    'DH[cipher suites using DH, including anonymous DH, ephemeral DH and fixed DH]' \
    'kECDHr[cipher suites using fixed ECDH key agreement signed by CAs with RSA keys]' \
    'kECDHe[cipher suites using fixed ECDH key agreement signed by CAs with ECDSA keys]' \
    'kECDH[cipher suites using fixed ECDH key agreement]' \
    {kECDHE,kEECDH}'[cipher suites using ephemeral ECDH key agreement, including anonymous cipher suites]' \
    {ECDHE,kEECDH}'[cipher suites using authenticated ephemeral ECDH key agreement]' \
    'AECDH[anonymous Elliptic Curve Diffie Hellman cipher suites]' \
    'ECDH[cipher suites using ECDH key exchange, including anonymous, ephemeral and fixed ECDH]' \
    'aRSA[cipher suites using RSA authentication]' \
    {aDSS,DSS}'[cipher suites using DSS authentication]' \
    'aDH[cipher suites effectively using DH authentication]' \
    'aECDH[cipher suites effectively using ECDH authentication]' \
    {aECDSA,ECDSA}'[cipher suites using ECDSA authentication]' \
    'TLSv1.2[TLSv1.2 cipher suites]' \
    'TLSv1[TLSv1.0 cipher suites]' \
    'SSLv3[SSLv3.0 cipher suites]' \
    'SSLv2[SSLv2.0 cipher suites]' \
    'AES128[cipher suites using 128 bit AES]' \
    'AES256[cipher suites using 256 bit AES]' \
    'AES[cipher suites using AES]' \
    'AESGCM[AES in Galois Counter Mode (GCM)]' \
    'CAMELLIA128[cipher suites using 128 bit CAMELLIA]' \
    'CAMELLIA256[cipher suites using 256 bit CAMELLIA]' \
    'CAMELLIA[cipher suites using CAMELLIA]' \
    '3DES[cipher suites using triple DES]' \
    'DES[cipher suites using DES (not triple DES)]' \
    'RC4[cipher suites using RC4]' \
    'RC2[cipher suites using RC2]' \
    'IDEA[cipher suites using IDEA]' \
    'SEED[cipher suites using SEED]' \
    'MD5[cipher suites using MD5]' \
    {SHA1,SHA}'[cipher suites using SHA1]' \
    'SHA256[cipher suites using SHA256]' \
    'SHA384[cipher suites using SHA284]' \
    'aGOST[cipher suites using GOST R 34.10 for authentication]' \
    'aGOST01[cipher suites using GOST R 34.10-2001 authentication]' \
    'aGOST94[cipher suites using GOST R 34.10-94 authentication]' \
    'kGOST[cipher suites, using VKO 34.10 key exchange]' \
    'GOST94[cipher suites, using HMAC based on GOST R 34.11-94]' \
    'GOST89MAC[cipher suites using GOST 28147-89 MAC instead of HMAC]' \
    'PSK[cipher suites using pre-shared keys (PSK)]' \
    'SUITEB128[suite B mode operation using 128 or 192 bit level of security]' \
    'SUITEB128ONLY[suite B mode operation using 128 bit level of security]' \
    'SUITEB192[suite B mode operation using 192 bit level of security]' \
    )
  # FIXME: support !, + and - before each cipher suite
  _values -s : 'cipher suite' ${ciphers}
}

_openssl_mac_algorithms() {
  # openssl list -mac-algorithms
  local algorithms=(
    BLAKE2BMAC BLAKE2SMAC CMAC HMAC KMAC128 KMAC256 SIPHASH POLY1305
  )

  _values algorithms $algorithms
}

_openssl_macopts() {
  local -a options=(
    'key\:[MAC key as an alphanumeric string]'
    'hexkey\:[MAC key in hexadecimal form]'
    'iv\:[IV as an alphanumeric string to be used by GMAC]'
    'hexiv\:[IV in hexadecimal form to be used by GMAC]'
    'size\:[output length to be used by KMAC128 or KMAC256]'
    'custom\:[customization string to be used by KMAC128 or KMAC256]'
    'digest\:[digest]'
    'cipher\:[cipher]'
  )

  _values 'options' ${options}
}

_openssl_name_display_options() {
  local -a options=(
    'compat:display the name using an old format from previous OpenSSL versions'
    'RFC2253:display the name using the format defined in RFC 2253'
    'oneline:display the name in one line more readable RFC 2253'
    'multiline:display the name using multiple lines'
    'esc_2253:escape the "special" characters in a field, as required by RFC 2253'
    'esc_2254:escape the "special" characters in a field as required by RFC 2254 in a field'
    'esc_ctrl:escape non-printable ASCII characters'
    'esc_msb:escape any characters with the most significant bit set'
    'use_quote:escapes some characters by surrounding the entire string with quotation marks'
    'utf8:convert all strings to UTF-8 format first as required by RFC 2253'
    'ignore_type:not attempt to interpret multibyte characters in any way'
    'show_type:display the type of the ASN1 character string before the value'
    'dump_der:output in hex format are displayed using the DER encoding of the field'
    'dump_nostr:dump non-character strings, such as ASN.1 OCTET STRING'
    'dump_all:dump all fields'
    'dump_unknown:dump any field whose OID is not recognised by OpenSSL'
    'sep_comma_plus:set comma as a separator'
    'sep_comma_plus_space:set comma as a separator and put space after the separator'
    'sep_semi_plus_space:set semi-colon as a separator and put space after the separator'
    'sep_multiline:start each field on its own line'
    'dn_rev:reverse the fields of the DN as required by RFC 2253'
    'nofname:does not display the field at all'
    'sname:use short name form'
    'lname:use long name form'
    'oid:represent the OID in numerical form'
    'align:align field values'
    'space_eq:place spaces round the equal sign'
  )

  _values 'options' ${options}
}

_openssl_pass_phrase_options() {
  local -a options=(
    'pass[actual password]:password'
    'env[obtain password from the environment variable]:var:_parameters -g "*export*"'
    'file[read the password from the file]:file:_files'
    'fd[read the password from the file descriptor number]:number'
    'stdin[read the password from standard input]'
  )

  _values -S : 'options' ${options}
}

_openssl_signature_algorithms() {
  local -a algorithms=(
    RSA DSA ECDSA
    SHA1 SHA224 SHA224 SHA384 SHA512
    ecdsa_secp256r1_sha256 ed25519 rsa_pss_pss_sha256
  )

  _values -s ':' algorithms $algorithms
}

_openssl_text_printing_options() {
  local -a options=(
    'compatible[use the old format]'
    'no_header[do not print header information]'
    'no_version[do not print out the version number]'
    'no_serial[do not print the serial number]'
    'no_signame[do not print out the signature algorithm used]'
    'no_validity[do not print the validity]'
    'no_subject[do not print out the subject name]'
    'no_issuer[do not print out the issuer name]'
    'no_pubkey[do not print out the public key]'
    'no_sigdump[do not give a hexadecimal dump of the certificate signature]'
    'no_aux[do not print out certificate trust information]'
    'no_extensions[do not print out any X509V3 extensions]'
    'ext_default[retain default extension behavior]'
    'ext_error[print an error message for unsupported certificate extensions]'
    'ext_parse[ASN1 parse unsupported extensions]'
    'ext_dump[Hex dump unsupported extensions]'
    'ca_default[equivalent to no_issuer, no_pubkey, no_header and no_version]'
  )

  _values -s , options $options
}

_openssl_tls_protocols() {
  local -a protocols=(SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 DTLSv1 DTLSv1.2 None)
  _values protocols $protocols
}

_openssl "$@"

# Local Variables:
# mode: Shell-Script
# sh-indentation: 2
# indent-tabs-mode: nil
# sh-basic-offset: 2
# End:
# vim: ft=zsh sw=2 ts=2 et