Compare commits
644 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
815aab772b | ||
|
|
b771738a3a | ||
|
|
7c2a68c719 | ||
|
|
e2b51a8705 | ||
|
|
bb3e0f474b | ||
|
|
02c3262be8 | ||
|
|
55f1fc5a73 | ||
|
|
7ce0835b74 | ||
|
|
c295fce45c | ||
|
|
79d6d1ff2b | ||
|
|
cf9978bc0e | ||
|
|
22e80b8c71 | ||
|
|
2260363648 | ||
|
|
9780fd6ba2 | ||
|
|
106d613805 | ||
|
|
bdede43afe | ||
|
|
8b2c370b86 | ||
|
|
0e2cd8219a | ||
|
|
749f837d36 | ||
|
|
8d521bacbb | ||
|
|
dbe0672dc4 | ||
|
|
45c83e2772 | ||
|
|
6af4f91674 | ||
|
|
8d2e9e783d | ||
|
|
5f0e5e2e51 | ||
|
|
d598f156a7 | ||
|
|
88c5bd81c7 | ||
|
|
01fc84f5e0 | ||
|
|
a02a962f7d | ||
|
|
9ba802ad43 | ||
|
|
850e93ee85 | ||
|
|
d3104955dd | ||
|
|
1b3e0c8a15 | ||
|
|
0d9f37be5b | ||
|
|
aef0517dcf | ||
|
|
39e692fac5 | ||
|
|
e8fc907da3 | ||
|
|
ccb2fd49ca | ||
|
|
390d71f1e5 | ||
|
|
89bd6d6168 | ||
|
|
fab6ea4727 | ||
|
|
ed966a09ac | ||
|
|
69ee79d435 | ||
|
|
124c05d058 | ||
|
|
3629bb6f26 | ||
|
|
d2e48e8d1f | ||
|
|
179758010a | ||
|
|
1c3f5b5f57 | ||
|
|
b9341856b1 | ||
|
|
ef86438a10 | ||
|
|
d7a768ea91 | ||
|
|
958c1811b0 | ||
|
|
49fc65f366 | ||
|
|
0202c20ca3 | ||
|
|
e3ac3f40bf | ||
|
|
3b064fdb02 | ||
|
|
b6d968b378 | ||
|
|
efd2c53843 | ||
|
|
b39a712076 | ||
|
|
d861eb16dd | ||
|
|
2e37753790 | ||
|
|
41fea135ad | ||
|
|
628c3b338a | ||
|
|
6686092edf | ||
|
|
aabaf97935 | ||
|
|
a9b9f818a1 | ||
|
|
801a236413 | ||
|
|
2f5ecb4267 | ||
|
|
d4f85a323f | ||
|
|
62b211990f | ||
|
|
d2b169dae6 | ||
|
|
9f3cf9907f | ||
|
|
06577cbf9c | ||
|
|
3331908a1d | ||
|
|
dedbcc6570 | ||
|
|
d8a9a7fa11 | ||
|
|
ee5b8b1f44 | ||
|
|
7ad3208937 | ||
|
|
995f9a9533 | ||
|
|
844c3c445a | ||
|
|
18eaa3d09e | ||
|
|
4121ac34cb | ||
|
|
d79090a00a | ||
|
|
98f91769e3 | ||
|
|
f0b8a2e467 | ||
|
|
2024379f17 | ||
|
|
2d8b7225e4 | ||
|
|
865c613de3 | ||
|
|
db858adcf8 | ||
|
|
4db16294ba | ||
|
|
f40a328d43 | ||
|
|
1b5293a977 | ||
|
|
bbff79636f | ||
|
|
63c7bda0c2 | ||
|
|
08879ed512 | ||
|
|
63177bdf14 | ||
|
|
6b0583b7c4 | ||
|
|
ae72202ad9 | ||
|
|
0b1c2a1048 | ||
|
|
576de0eaa2 | ||
|
|
a6b6648a62 | ||
|
|
8c5ce91d07 | ||
|
|
702bc48b1c | ||
|
|
d9cb5433b1 | ||
|
|
a335c1b2f5 | ||
|
|
c3e2604702 | ||
|
|
9eac3c6593 | ||
|
|
2a028e59e4 | ||
|
|
e49b54150e | ||
|
|
27d5786390 | ||
|
|
0c112d2162 | ||
|
|
bd668ec702 | ||
|
|
92d623bd64 | ||
|
|
acb629a47f | ||
|
|
546405dc58 | ||
|
|
27494508bf | ||
|
|
d922e3f80b | ||
|
|
77ff62a4c8 | ||
|
|
914fadcec7 | ||
|
|
7c4a323dc4 | ||
|
|
487963d17a | ||
|
|
a0e5b31799 | ||
|
|
9e688cb833 | ||
|
|
546eb4d391 | ||
|
|
7602aed0dc | ||
|
|
4436245ab8 | ||
|
|
0dd632456f | ||
|
|
404670691c | ||
|
|
effd08114a | ||
|
|
404b7f1790 | ||
|
|
a16482f972 | ||
|
|
913267e68a | ||
|
|
834c16d5c7 | ||
|
|
55fee497bb | ||
|
|
a99f75fccd | ||
|
|
953fe86b9a | ||
|
|
5faeeb5c61 | ||
|
|
2474bce3db | ||
|
|
25f750c223 | ||
|
|
297804b2d9 | ||
|
|
ab298d0264 | ||
|
|
83b58057dd | ||
|
|
fe1042f338 | ||
|
|
e088d1d856 | ||
|
|
58ccea26ad | ||
|
|
f97ad04c7f | ||
|
|
28c0af386f | ||
|
|
4c6af10cbd | ||
|
|
bf303ae757 | ||
|
|
70afbb8393 | ||
|
|
7eee39f1ec | ||
|
|
7f4ceb51a4 | ||
|
|
899fc30e9b | ||
|
|
941a69a4d2 | ||
|
|
3a170b655b | ||
|
|
e48901e20b | ||
|
|
dd140f5167 | ||
|
|
73442137c5 | ||
|
|
34755f8a6b | ||
|
|
691ce7ca2a | ||
|
|
3843d850b5 | ||
|
|
637228e7ee | ||
|
|
ec8aadb518 | ||
|
|
1ff853ada9 | ||
|
|
6f9401f174 | ||
|
|
53253db0dc | ||
|
|
e56e09b6a4 | ||
|
|
e3be399dea | ||
|
|
6378eff9db | ||
|
|
4ff5f4486f | ||
|
|
79abbeaa81 | ||
|
|
b565a0c7eb | ||
|
|
69aa335871 | ||
|
|
9ccdcdb821 | ||
|
|
1c48c9c456 | ||
|
|
a68125e455 | ||
|
|
57e02abb50 | ||
|
|
b24ee29fa6 | ||
|
|
e75793e896 | ||
|
|
e8a64c9937 | ||
|
|
af4488357c | ||
|
|
91a78bc38b | ||
|
|
800c232c09 | ||
|
|
43fc870270 | ||
|
|
5c7fa43d87 | ||
|
|
894b924f1d | ||
|
|
fd8c9d7336 | ||
|
|
ad614ada7e | ||
|
|
38a4dccceb | ||
|
|
e0e0a96cb3 | ||
|
|
b88778bc76 | ||
|
|
2ddb5c700d | ||
|
|
93c67e2f77 | ||
|
|
e2783971ea | ||
|
|
3aecfe5655 | ||
|
|
4256cfbf19 | ||
|
|
63b50746ec | ||
|
|
9fd7584a84 | ||
|
|
c482f6d8dc | ||
|
|
2e6dbcd5c6 | ||
|
|
dab71dbf0a | ||
|
|
8bd3ece403 | ||
|
|
965c55e283 | ||
|
|
3013d2e93f | ||
|
|
d3bb880866 | ||
|
|
29e4607ed9 | ||
|
|
d52be16cc4 | ||
|
|
04ada473d1 | ||
|
|
3ee176ef04 | ||
|
|
d2cc0eae2d | ||
|
|
8ae761063c | ||
|
|
2dd3736444 | ||
|
|
cd1d1955d9 | ||
|
|
0245eee724 | ||
|
|
b86f547dbf | ||
|
|
e6da0fa4a1 | ||
|
|
367bc97979 | ||
|
|
18dfc9b6b2 | ||
|
|
72a60af503 | ||
|
|
b6971883be | ||
|
|
e9e9239c47 | ||
|
|
5894cdfdc5 | ||
|
|
a01979cfdc | ||
|
|
22231d7547 | ||
|
|
a548913e44 | ||
|
|
8f94c13a3e | ||
|
|
c85871c443 | ||
|
|
348cb7391b | ||
|
|
b09929fd07 | ||
|
|
9e1a6f284b | ||
|
|
00641a9d6b | ||
|
|
8c6bc774db | ||
|
|
a29c789e57 | ||
|
|
93a4e96255 | ||
|
|
8d5a91c334 | ||
|
|
ea18d84de3 | ||
|
|
947dfbd143 | ||
|
|
aa5cfbe239 | ||
|
|
bc4e47a321 | ||
|
|
458d9e4ccb | ||
|
|
5cd0581e8e | ||
|
|
2df87cfd59 | ||
|
|
b1d01fbc0c | ||
|
|
ef7721092d | ||
|
|
b07ebe44ed | ||
|
|
59c578cf04 | ||
|
|
f42777b17c | ||
|
|
1396143c66 | ||
|
|
a062c62cf0 | ||
|
|
cb2f4c2287 | ||
|
|
ba7f82e41b | ||
|
|
ef69870ea2 | ||
|
|
0c92bba84a | ||
|
|
09ce916551 | ||
|
|
5948898e54 | ||
|
|
aba29697d3 | ||
|
|
71ee9439ca | ||
|
|
864cd9fa81 | ||
|
|
415f399b2c | ||
|
|
0725cbb165 | ||
|
|
ee5215bd31 | ||
|
|
44af821d80 | ||
|
|
a964d05d4a | ||
|
|
bd9a2b25a7 | ||
|
|
9eeee0930c | ||
|
|
80aa086667 | ||
|
|
1392b006e2 | ||
|
|
6422ffb1b2 | ||
|
|
3524ac09b3 | ||
|
|
76cad11b64 | ||
|
|
361c9c336e | ||
|
|
917236c108 | ||
|
|
07c49e517e | ||
|
|
4c1891cc10 | ||
|
|
339d09fbf3 | ||
|
|
19430b114e | ||
|
|
321c076ab3 | ||
|
|
c624427e31 | ||
|
|
0390aba73b | ||
|
|
4994e75d2c | ||
|
|
52c942f4b3 | ||
|
|
6440ee04ef | ||
|
|
bf86580bec | ||
|
|
0f815628b4 | ||
|
|
115cb730b0 | ||
|
|
2512c93df2 | ||
|
|
9bf748befb | ||
|
|
6834b97ff4 | ||
|
|
d82a49bee2 | ||
|
|
a10c43b1cc | ||
|
|
5e54dd22fb | ||
|
|
cdc90c7e9d | ||
|
|
14b5439347 | ||
|
|
f5e6d57c47 | ||
|
|
2afdc16fc9 | ||
|
|
2c89ef5228 | ||
|
|
0745d66927 | ||
|
|
88c61d252f | ||
|
|
285884c925 | ||
|
|
bcc4ca0285 | ||
|
|
b1c77a7ea5 | ||
|
|
5d8a44612d | ||
|
|
b1eb1224f5 | ||
|
|
24f4bdb533 | ||
|
|
83767b861e | ||
|
|
52f581ffc9 | ||
|
|
a3a2605115 | ||
|
|
bf5772eb54 | ||
|
|
10b2a34529 | ||
|
|
c2145384a9 | ||
|
|
63afe3016c | ||
|
|
15cb335e66 | ||
|
|
fb1b9b4140 | ||
|
|
a1cb6a7328 | ||
|
|
3456add537 | ||
|
|
a523219f6c | ||
|
|
2977f6ed30 | ||
|
|
b8de619fbe | ||
|
|
4f3d72d98c | ||
|
|
a774c0c5f2 | ||
|
|
772e1c003f | ||
|
|
58da8757f1 | ||
|
|
3cd33cdd8b | ||
|
|
fe37bb7e9b | ||
|
|
c0876cc8c6 | ||
|
|
c7db3d18ad | ||
|
|
2e478fdcf4 | ||
|
|
677617bc0b | ||
|
|
b187eb0ee3 | ||
|
|
25df3c8b51 | ||
|
|
58c273845f | ||
|
|
ac1021373c | ||
|
|
7a7f98a32c | ||
|
|
6bc52f076e | ||
|
|
b976b5fd52 | ||
|
|
a2be3535b5 | ||
|
|
41b0520416 | ||
|
|
f0347fbce8 | ||
|
|
83f6a24026 | ||
|
|
3ab1cc7a8f | ||
|
|
9f5d750744 | ||
|
|
4c1fdf1d81 | ||
|
|
440ede3b54 | ||
|
|
a6fcef01c0 | ||
|
|
9df403043b | ||
|
|
862d784161 | ||
|
|
b397bc45af | ||
|
|
d991566f2b | ||
|
|
9ba53102f9 | ||
|
|
e037c0fcb8 | ||
|
|
69c75a178b | ||
|
|
d5d414b16f | ||
|
|
47a68e2929 | ||
|
|
9e5dcb03f2 | ||
|
|
1a909c8e5e | ||
|
|
53671518fd | ||
|
|
5debc1ba5a | ||
|
|
b1e5c8b1ed | ||
|
|
ff2c7ffefd | ||
|
|
78abc9b64f | ||
|
|
c25b6f3e26 | ||
|
|
af5a7178cb | ||
|
|
5cfbe7ac6a | ||
|
|
e5d65306e7 | ||
|
|
afaa2387c8 | ||
|
|
541458c1c1 | ||
|
|
90898e99c9 | ||
|
|
436afb8f57 | ||
|
|
7a1b59d605 | ||
|
|
5b0a0e5692 | ||
|
|
cc8866ac3c | ||
|
|
bc0809a17d | ||
|
|
42cbd0111b | ||
|
|
25e3f66e3e | ||
|
|
ed20fd7087 | ||
|
|
80606fc0f0 | ||
|
|
47431f66bb | ||
|
|
6f59406067 | ||
|
|
aa619c81c0 | ||
|
|
f90e00500c | ||
|
|
03a4c6bd26 | ||
|
|
043ad63a52 | ||
|
|
24ece94e99 | ||
|
|
261463542f | ||
|
|
9a83e3350b | ||
|
|
13caf731a2 | ||
|
|
6252829f4b | ||
|
|
5bb89d7552 | ||
|
|
5360f5ad04 | ||
|
|
8ce5dee00d | ||
|
|
6b1edf5625 | ||
|
|
973a3fede1 | ||
|
|
83d98cf089 | ||
|
|
bbaec65b73 | ||
|
|
c1e5a5c425 | ||
|
|
cab98be606 | ||
|
|
78d91428b5 | ||
|
|
342e0171f0 | ||
|
|
fd19f49d7b | ||
|
|
a586bdc940 | ||
|
|
75bf48368d | ||
|
|
f63b9f05a3 | ||
|
|
e3045dc339 | ||
|
|
01855a4f64 | ||
|
|
03c6bcc159 | ||
|
|
23ca9d2832 | ||
|
|
e423da2d12 | ||
|
|
8aaeb30393 | ||
|
|
111131e3e4 | ||
|
|
5c317d5a35 | ||
|
|
a14b7cc276 | ||
|
|
14662f547e | ||
|
|
ac950b28aa | ||
|
|
1bbe1b6a8f | ||
|
|
598b326f61 | ||
|
|
7942db5e89 | ||
|
|
f99c101559 | ||
|
|
99fdb2bd0b | ||
|
|
bbb1cb61f6 | ||
|
|
020b2384c6 | ||
|
|
c82a87a18e | ||
|
|
7890672725 | ||
|
|
812d7a613f | ||
|
|
f0614f4acd | ||
|
|
c1f6a7db9c | ||
|
|
d49e496940 | ||
|
|
063186b62e | ||
|
|
0860115156 | ||
|
|
95ea489784 | ||
|
|
7c33346960 | ||
|
|
cf658e4c5c | ||
|
|
09b1fe9a0d | ||
|
|
66a2ad76b7 | ||
|
|
e3a657d22b | ||
|
|
9452c01672 | ||
|
|
170adae336 | ||
|
|
7edecbd3a8 | ||
|
|
9f5ef88880 | ||
|
|
0bc7dd9034 | ||
|
|
d0329473bd | ||
|
|
c9ef7f3cd5 | ||
|
|
1b830c3fb7 | ||
|
|
f2575138eb | ||
|
|
4ee7e0d3a9 | ||
|
|
cefad46cf5 | ||
|
|
00359a1a55 | ||
|
|
a5c2ddb219 | ||
|
|
40e59db37c | ||
|
|
d7a7c379a8 | ||
|
|
c0a4bc4202 | ||
|
|
e02dbde2f7 | ||
|
|
eb5fda588f | ||
|
|
11f35dd566 | ||
|
|
67640ed599 | ||
|
|
562fe79f4c | ||
|
|
c3b6e87244 | ||
|
|
bc304565e7 | ||
|
|
245f5f3a11 | ||
|
|
b0bc1c770e | ||
|
|
7fe3fabf24 | ||
|
|
a5d7f8a718 | ||
|
|
e655b561a7 | ||
|
|
7ab650098c | ||
|
|
4866e9ff8a | ||
|
|
8461129456 | ||
|
|
9e2755abae | ||
|
|
0a38b5a9ef | ||
|
|
4b4d312018 | ||
|
|
dcbb45cc9d | ||
|
|
d4de2a408f | ||
|
|
a5ba1a0007 | ||
|
|
55ffc9b2e4 | ||
|
|
b0ea53184d | ||
|
|
1a0b085377 | ||
|
|
810ddeb4ca | ||
|
|
2d6cd9eb16 | ||
|
|
724dd6f830 | ||
|
|
84a5ce7607 | ||
|
|
9a8a1c752b | ||
|
|
888f4ccaab | ||
|
|
53adf0e6a4 | ||
|
|
6abac82f13 | ||
|
|
a1cfde765a | ||
|
|
3187366cc5 | ||
|
|
2251a6f2b6 | ||
|
|
d8a11973e2 | ||
|
|
910386027d | ||
|
|
35cad33d51 | ||
|
|
847fac25f8 | ||
|
|
3595ff9e51 | ||
|
|
eb6296e892 | ||
|
|
f645165ee2 | ||
|
|
38f4705b1d | ||
|
|
5760ded1ce | ||
|
|
f92de22b8d | ||
|
|
b6985c7e8d | ||
|
|
aa9addf532 | ||
|
|
7fcd1ba96d | ||
|
|
65e124055c | ||
|
|
85d8db21d2 | ||
|
|
42ec251b55 | ||
|
|
b7ba577339 | ||
|
|
d5dd6575c1 | ||
|
|
b94b0f67c5 | ||
|
|
e04dbfa3ee | ||
|
|
e06a209e72 | ||
|
|
cebfbd9a25 | ||
|
|
5fd23d38d5 | ||
|
|
6a5845c875 | ||
|
|
f72f35e9bd | ||
|
|
c1a106fc68 | ||
|
|
7e0591a377 | ||
|
|
950c39c2e6 | ||
|
|
38470bd351 | ||
|
|
15048f4c02 | ||
|
|
6977e9e89f | ||
|
|
7e02c09861 | ||
|
|
7192a5291f | ||
|
|
69a91815b8 | ||
|
|
402d81bb72 | ||
|
|
78aed77cf3 | ||
|
|
9693c7ccf8 | ||
|
|
2daaf3fdea | ||
|
|
90d5f85511 | ||
|
|
8f8895697d | ||
|
|
3f5e3f095e | ||
|
|
b1e7bf4d54 | ||
|
|
18b87e65e3 | ||
|
|
e5123d266b | ||
|
|
4dffa0c33f | ||
|
|
4f58ebd270 | ||
|
|
8abc51c2b3 | ||
|
|
21c5263767 | ||
|
|
af4832e145 | ||
|
|
a9d8bea33c | ||
|
|
3db28a1e12 | ||
|
|
cc34a7149e | ||
|
|
f4ddd66b03 | ||
|
|
9d3b02e58a | ||
|
|
e8fd63bae3 | ||
|
|
eb24a2157a | ||
|
|
2765775535 | ||
|
|
41598534b6 | ||
|
|
041d473c0a | ||
|
|
9f35b74c1d | ||
|
|
9f167894a2 | ||
|
|
b1ab0ec473 | ||
|
|
2fd79b525e | ||
|
|
2c0dce4c39 | ||
|
|
a686ed7891 | ||
|
|
7a6260321d | ||
|
|
fda5e50638 | ||
|
|
404bbeddfd | ||
|
|
70a4eef049 | ||
|
|
c9fed802b3 | ||
|
|
0d8e0e04c9 | ||
|
|
a6499d44bb | ||
|
|
e66f6dff92 | ||
|
|
d3169a565e | ||
|
|
81f7d17822 | ||
|
|
38ddad99af | ||
|
|
c3fb53b756 | ||
|
|
6552a9cbfd | ||
|
|
0d91e775ca | ||
|
|
60337266ab | ||
|
|
9943bb6869 | ||
|
|
8ee891fcbf | ||
|
|
692562470b | ||
|
|
be50654564 | ||
|
|
be1e787ce6 | ||
|
|
693ef3178f | ||
|
|
d85e2a2937 | ||
|
|
9a27bb2c03 | ||
|
|
44e0a1f100 | ||
|
|
eed97733c8 | ||
|
|
79fb47e9e8 | ||
|
|
9acf6ea99f | ||
|
|
b9eace6569 | ||
|
|
33ec3a5784 | ||
|
|
15420eb44a | ||
|
|
3ecf146077 | ||
|
|
af7aa52364 | ||
|
|
db2b8bbc78 | ||
|
|
f50dd20cb6 | ||
|
|
fe0f33e32b | ||
|
|
91e120ca95 | ||
|
|
05c5c422fd | ||
|
|
3c19702299 | ||
|
|
71862e9769 | ||
|
|
45c15a65ad | ||
|
|
753a7d07b1 | ||
|
|
637c160c83 | ||
|
|
c4620a30c6 | ||
|
|
c2430b87f7 | ||
|
|
1553447385 | ||
|
|
0dd0df84d7 | ||
|
|
9043cf9aa7 | ||
|
|
1d325624be | ||
|
|
a4c9dd4af3 | ||
|
|
bb5ab2b43f | ||
|
|
1a40795886 | ||
|
|
d3fff74ae8 | ||
|
|
d207897458 | ||
|
|
6238b4a20a | ||
|
|
89dd50b3ce | ||
|
|
a97a90cf05 | ||
|
|
1085e79447 | ||
|
|
afec43351c | ||
|
|
23bab6336e | ||
|
|
e1d442e65b | ||
|
|
7fbda61609 | ||
|
|
dcfe1dfa8b | ||
|
|
52a06adc08 | ||
|
|
642d5bd54d | ||
|
|
1166a6c3bf | ||
|
|
f9866cd44f | ||
|
|
129b6b9d84 | ||
|
|
be04bc4064 | ||
|
|
19dc6ce1eb | ||
|
|
3fe5d562fb | ||
|
|
ce0641f093 | ||
|
|
fdb8909c32 | ||
|
|
2adf2cf12b | ||
|
|
ff9fe6fe04 | ||
|
|
3744e31e16 | ||
|
|
90d8a799fe | ||
|
|
7cc6c9b2f2 | ||
|
|
7d0c6c9442 | ||
|
|
69652d5dad | ||
|
|
77448362ce | ||
|
|
3eab162dc2 | ||
|
|
bbae793eb3 | ||
|
|
2aaba8bd7a | ||
|
|
82d3ac948b | ||
|
|
25984aa183 | ||
|
|
34d700309c | ||
|
|
1867cf3ace | ||
|
|
196a855d2a | ||
|
|
4c47aca508 | ||
|
|
138884f5b8 | ||
|
|
43753698da | ||
|
|
5465f0bb4a | ||
|
|
305eddd62d | ||
|
|
4b732dad19 |
@ -1,189 +1,303 @@
|
||||
restore_registry: &RESTORE_REGISTRY
|
||||
restore_cache:
|
||||
key: registry
|
||||
save_registry: &SAVE_REGISTRY
|
||||
save_cache:
|
||||
key: registry-{{ .BuildNum }}
|
||||
paths:
|
||||
- /usr/local/cargo/registry/index
|
||||
openssl_key: &OPENSSL_KEY
|
||||
key: lib-{{ checksum "~/lib_key" }}-{{ checksum "test/build_openssl.sh" }}
|
||||
restore_openssl: &RESTORE_OPENSSL
|
||||
restore_cache:
|
||||
<<: *OPENSSL_KEY
|
||||
save_openssl: &SAVE_OPENSSL
|
||||
save_cache:
|
||||
<<: *OPENSSL_KEY
|
||||
paths:
|
||||
- /openssl
|
||||
deps_key: &DEPS_KEY
|
||||
key: deps-1.19.0-{{ checksum "Cargo.lock" }}-{{ checksum "~/lib_key" }}-2
|
||||
restore_deps: &RESTORE_DEPS
|
||||
restore_cache:
|
||||
<<: *DEPS_KEY
|
||||
save_deps: &SAVE_DEPS
|
||||
save_cache:
|
||||
<<: *DEPS_KEY
|
||||
paths:
|
||||
- target
|
||||
- /usr/local/cargo/registry/cache
|
||||
version: 2.1
|
||||
|
||||
job: &JOB
|
||||
working_directory: ~/build
|
||||
docker:
|
||||
- image: rust:1.19.0
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt-get update
|
||||
- run: apt-get remove -y libssl-dev
|
||||
- run: ./test/add_target.sh
|
||||
- *RESTORE_REGISTRY
|
||||
- run: cargo generate-lockfile
|
||||
- *SAVE_REGISTRY
|
||||
- run: echo "${LIBRARY}-${VERSION}-${TARGET}" > ~/lib_key
|
||||
- *RESTORE_OPENSSL
|
||||
- run: ./test/build_openssl.sh
|
||||
- *SAVE_OPENSSL
|
||||
- *RESTORE_DEPS
|
||||
- run: cargo run --manifest-path=systest/Cargo.toml --target $TARGET
|
||||
- run: |
|
||||
ulimit -c unlimited
|
||||
export PATH=$OPENSSL_DIR/bin:$PATH
|
||||
if [ "${NO_RUN}" = "1" ]; then
|
||||
TEST_ARGS=--no-run
|
||||
fi
|
||||
cargo test \
|
||||
--manifest-path=openssl/Cargo.toml \
|
||||
--target $TARGET \
|
||||
--all-features \
|
||||
$TEST_ARGS
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/core_dumps
|
||||
find . -name "core.*" -exec cp \{\} /tmp/core_dumps \;
|
||||
cp target/$TARGET/debug/openssl-* /tmp/core_dumps
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: /tmp/core_dumps
|
||||
- *SAVE_DEPS
|
||||
|
||||
macos_job: &MACOS_JOB
|
||||
macos:
|
||||
xcode: "9.0"
|
||||
environment:
|
||||
RUSTUP_HOME: /usr/local/rustup
|
||||
CARGO_HOME: /usr/local/cargo
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo mkdir /opt
|
||||
- run: sudo chown -R $USER /usr/local /opt
|
||||
- run: curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.19.0
|
||||
- run: sudo ln -s $CARGO_HOME/bin/* /usr/local/bin
|
||||
- *RESTORE_REGISTRY
|
||||
- run: cargo generate-lockfile
|
||||
- *SAVE_REGISTRY
|
||||
- run: echo "homebrew-x86_64-apple-darwin" > ~/lib_key
|
||||
- *RESTORE_DEPS
|
||||
- run: cargo run --manifest-path=systest/Cargo.toml
|
||||
- run: |
|
||||
PATH=/usr/local/opt/openssl/bin:$PATH
|
||||
cargo test --manifest-path=openssl/Cargo.toml --all-features
|
||||
- *SAVE_DEPS
|
||||
|
||||
openssl_110: &OPENSSL_110
|
||||
LIBRARY: openssl
|
||||
VERSION: 1.1.0g
|
||||
openssl_102: &OPENSSL_102
|
||||
LIBRARY: openssl
|
||||
VERSION: 1.0.2m
|
||||
openssl_101: &OPENSSL_101
|
||||
LIBRARY: openssl
|
||||
VERSION: 1.0.1u
|
||||
libressl_250: &LIBRESSL_250
|
||||
LIBRARY: libressl
|
||||
VERSION: 2.5.0
|
||||
libressl_263: &LIBRESSL_263
|
||||
LIBRARY: libressl
|
||||
VERSION: 2.6.3
|
||||
|
||||
x86_64: &X86_64
|
||||
TARGET: x86_64-unknown-linux-gnu
|
||||
i686: &I686
|
||||
TARGET: i686-unknown-linux-gnu
|
||||
armhf: &ARMHF
|
||||
TARGET: arm-unknown-linux-gnueabihf
|
||||
NO_RUN: 1
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_AR: arm-linux-gnueabihf-ar
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER: qemu-arm-static
|
||||
darwin: &DARWIN
|
||||
TARGET: x86_64-apple-darwin
|
||||
|
||||
base: &BASE
|
||||
RUST_BACKTRACE: 1
|
||||
OPENSSL_DIR: /openssl
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
x86_64-openssl-1.1.0:
|
||||
<<: *JOB
|
||||
linux:
|
||||
parameters:
|
||||
target:
|
||||
type: string
|
||||
library:
|
||||
type: string
|
||||
default: ""
|
||||
version:
|
||||
type: string
|
||||
default: ""
|
||||
vendored:
|
||||
type: boolean
|
||||
default: false
|
||||
no_run:
|
||||
type: boolean
|
||||
default: false
|
||||
image:
|
||||
type: string
|
||||
default: 1.33.0
|
||||
minimal_build:
|
||||
type: boolean
|
||||
default: false
|
||||
docker:
|
||||
- image: rust:<< parameters.image >>
|
||||
environment:
|
||||
<<: [*OPENSSL_110, *X86_64, *BASE]
|
||||
x86_64-openssl-1.0.2:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_102, *X86_64, *BASE]
|
||||
x86_64-openssl-1.0.1:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_101, *X86_64, *BASE]
|
||||
i686-openssl-1.1.0:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_110, *I686, *BASE]
|
||||
i686-openssl-1.0.2:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_102, *I686, *BASE]
|
||||
i686-openssl-1.0.1:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_101, *I686, *BASE]
|
||||
armhf-openssl-1.1.0:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_110, *ARMHF, *BASE]
|
||||
armhf-openssl-1.0.2:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_102, *ARMHF, *BASE]
|
||||
armhf-openssl-1.0.1:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*OPENSSL_101, *ARMHF, *BASE]
|
||||
x86_64-libressl-2.5.0:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*LIBRESSL_250, *X86_64, *BASE]
|
||||
x86_64-libressl-2.6.3:
|
||||
<<: *JOB
|
||||
environment:
|
||||
<<: [*LIBRESSL_263, *X86_64, *BASE]
|
||||
RUST_BACKTRACE: 1
|
||||
OPENSSL_DIR: /opt/openssl
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_AR: arm-linux-gnueabihf-ar
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER: qemu-arm-static
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt-get update
|
||||
- run: apt-get remove -y libssl-dev
|
||||
- run: |
|
||||
case "<< parameters.target >>" in
|
||||
"i686-unknown-linux-gnu")
|
||||
apt-get install -y --no-install-recommends gcc-multilib
|
||||
;;
|
||||
"x86_64-unknown-linux-musl")
|
||||
apt-get install -y --no-install-recommends musl-tools
|
||||
;;
|
||||
"arm-unknown-linux-gnueabihf")
|
||||
dpkg --add-architecture armhf
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
libc6-dev:armhf \
|
||||
qemu-user-static
|
||||
;;
|
||||
"x86_64-unknown-linux-gnu")
|
||||
exit 0
|
||||
esac
|
||||
|
||||
rustup target add << parameters.target >>
|
||||
- unless:
|
||||
condition: << parameters.vendored >>
|
||||
steps:
|
||||
- restore_cache:
|
||||
key: openssl-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>
|
||||
- run: |
|
||||
if [ -d "$OPENSSL_DIR" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "<< parameters.library >>" in
|
||||
"libressl")
|
||||
URL="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-<< parameters.version >>.tar.gz"
|
||||
;;
|
||||
"openssl")
|
||||
URL="https://openssl.org/source/openssl-<< parameters.version >>.tar.gz"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "<< parameters.target >>" in
|
||||
"x86_64-unknown-linux-gnu")
|
||||
OS_COMPILER=linux-x86_64
|
||||
OS_FLAGS=""
|
||||
;;
|
||||
"i686-unknown-linux-gnu")
|
||||
OS_COMPILER=linux-elf
|
||||
OS_FLAGS=-m32
|
||||
;;
|
||||
"arm-unknown-linux-gnueabihf")
|
||||
OS_COMPILER=linux-armv4
|
||||
OS_FLAGS=""
|
||||
export AR=arm-linux-gnueabihf-ar
|
||||
export CC=arm-linux-gnueabihf-gcc
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir /tmp/build
|
||||
cd /tmp/build
|
||||
|
||||
curl -L $URL | tar --strip-components=1 -xzf -
|
||||
|
||||
case "<< parameters.library >>" in
|
||||
"openssl")
|
||||
./Configure --prefix=$OPENSSL_DIR $OS_COMPILER -fPIC -g $OS_FLAGS no-shared
|
||||
;;
|
||||
"libressl")
|
||||
./configure --prefix=$OPENSSL_DIR --disable-shared --with-pic
|
||||
;;
|
||||
esac
|
||||
|
||||
make
|
||||
make install_sw
|
||||
- save_cache:
|
||||
key: openssl-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>
|
||||
paths:
|
||||
- /opt/openssl
|
||||
- restore_cache:
|
||||
key: registry
|
||||
- run: cargo generate-lockfile
|
||||
- when:
|
||||
condition: << parameters.minimal_build >>
|
||||
steps:
|
||||
- run: cargo update -p pkg-config --precise 0.3.14
|
||||
- save_cache:
|
||||
key: registry-{{ .BuildNum }}
|
||||
paths:
|
||||
- /usr/local/cargo/registry/index
|
||||
- restore_cache:
|
||||
key: deps-<< parameters.image >>-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>-{{ checksum "Cargo.lock" }}
|
||||
- run: |
|
||||
cargo build \
|
||||
--manifest-path=openssl/Cargo.toml \
|
||||
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
|
||||
--target << parameters.target >>
|
||||
- unless:
|
||||
condition: << parameters.minimal_build >>
|
||||
steps:
|
||||
- run: |
|
||||
cargo run \
|
||||
--manifest-path=systest/Cargo.toml \
|
||||
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
|
||||
--target << parameters.target >>
|
||||
- run: |
|
||||
cargo test \
|
||||
--manifest-path=openssl-errors/Cargo.toml \
|
||||
<<# parameters.vendored >>--features openssl-sys/vendored<</ parameters.vendored >> \
|
||||
--target << parameters.target >> \
|
||||
<<# parameters.no_run >>--no-run<</ parameters.no_run >>
|
||||
- run: |
|
||||
ulimit -c unlimited
|
||||
cargo test \
|
||||
--manifest-path=openssl/Cargo.toml \
|
||||
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
|
||||
--target << parameters.target >> \
|
||||
<<# parameters.no_run >>--no-run<</ parameters.no_run >>
|
||||
- save_cache:
|
||||
key: deps-<< parameters.image >>-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>-{{ checksum "Cargo.lock" }}
|
||||
paths:
|
||||
- /usr/local/cargo/registry/cache
|
||||
- target
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p /tmp/core_dumps
|
||||
find . -name "core.*" -exec cp \{\} /tmp/core_dumps \;
|
||||
cp target/<< parameters.target >>/debug/openssl-* /tmp/core_dumps
|
||||
when: on_fail
|
||||
- store_artifacts:
|
||||
path: /tmp/core_dumps
|
||||
|
||||
macos:
|
||||
<<: *MACOS_JOB
|
||||
parameters:
|
||||
vendored:
|
||||
type: boolean
|
||||
default: false
|
||||
image:
|
||||
type: string
|
||||
default: 1.33.0
|
||||
macos:
|
||||
xcode: "9.0"
|
||||
environment:
|
||||
RUST_BACKTRACE: 1
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo mkdir /opt
|
||||
- run: sudo chown -R $USER /usr/local/ /opt
|
||||
- run: curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain << parameters.image >>
|
||||
- run: sudo ln -s ~/.cargo/bin/* /usr/local/bin
|
||||
- run: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
key: deps-<< parameters.image >>-macos-<< parameters.vendored >>-{{ checksum "Cargo.lock" }}
|
||||
- run: |
|
||||
cargo run \
|
||||
--manifest-path=systest/Cargo.toml \
|
||||
<<# parameters.vendored >> --features vendored <</ parameters.vendored >>
|
||||
- run: |
|
||||
cargo test \
|
||||
--manifest-path=openssl-errors/Cargo.toml \
|
||||
<<# parameters.vendored >> --features openssl-sys/vendored <</ parameters.vendored >>
|
||||
- run: |
|
||||
cargo test \
|
||||
--manifest-path=openssl/Cargo.toml \
|
||||
<<# parameters.vendored >> --features vendored <</ parameters.vendored >>
|
||||
- save_cache:
|
||||
key: deps-<< parameters.image >>-macos-<< parameters.vendored >>-{{ checksum "Cargo.lock" }}
|
||||
paths:
|
||||
- ~/.cargo/registry/cache
|
||||
- target
|
||||
|
||||
openssl_111: &openssl_111
|
||||
library: openssl
|
||||
version: 1.1.1d
|
||||
openssl_110: &openssl_110
|
||||
library: openssl
|
||||
version: 1.1.0l
|
||||
openssl_102: &openssl_102
|
||||
library: openssl
|
||||
version: 1.0.2t
|
||||
openssl_101: &openssl_101
|
||||
library: openssl
|
||||
version: 1.0.1u
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
tests:
|
||||
test:
|
||||
jobs:
|
||||
- x86_64-openssl-1.1.0
|
||||
- x86_64-openssl-1.0.2
|
||||
- x86_64-openssl-1.0.1
|
||||
- i686-openssl-1.1.0
|
||||
- i686-openssl-1.0.2
|
||||
- i686-openssl-1.0.1
|
||||
- armhf-openssl-1.1.0
|
||||
- armhf-openssl-1.0.2
|
||||
- armhf-openssl-1.0.1
|
||||
- x86_64-libressl-2.5.0
|
||||
- x86_64-libressl-2.6.3
|
||||
- macos
|
||||
- linux:
|
||||
name: mimimal-version
|
||||
target: x86_64-unknown-linux-musl
|
||||
vendored: true
|
||||
image: 1.31.0
|
||||
minimal_build: true
|
||||
- linux:
|
||||
name: musl-vendored
|
||||
target: x86_64-unknown-linux-musl
|
||||
vendored: true
|
||||
- linux:
|
||||
name: x86_64-vendored
|
||||
target: x86_64-unknown-linux-gnu
|
||||
vendored: true
|
||||
- linux:
|
||||
<<: *openssl_111
|
||||
name: x86_64-openssl-1.1.1
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- linux:
|
||||
<<: *openssl_110
|
||||
name: x86_64-openssl-1.1.0
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- linux:
|
||||
<<: *openssl_102
|
||||
name: x86_64-openssl-1.0.2
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- linux:
|
||||
<<: *openssl_101
|
||||
name: x86_64-openssl-1.0.1
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- linux:
|
||||
name: i686-vendored
|
||||
target: i686-unknown-linux-gnu
|
||||
vendored: true
|
||||
- linux:
|
||||
<<: *openssl_111
|
||||
name: i686-openssl-1.1.1
|
||||
target: i686-unknown-linux-gnu
|
||||
- linux:
|
||||
<<: *openssl_110
|
||||
name: i686-openssl-1.1.0
|
||||
target: i686-unknown-linux-gnu
|
||||
- linux:
|
||||
<<: *openssl_102
|
||||
name: i686-openssl-1.0.2
|
||||
target: i686-unknown-linux-gnu
|
||||
- linux:
|
||||
name: armhf-vendored
|
||||
target: arm-unknown-linux-gnueabihf
|
||||
vendored: true
|
||||
no_run: true
|
||||
- linux:
|
||||
<<: *openssl_111
|
||||
name: armhf-openssl-1.1.1
|
||||
target: arm-unknown-linux-gnueabihf
|
||||
no_run: true
|
||||
- linux:
|
||||
<<: *openssl_110
|
||||
name: armhf-openssl-1.1.0
|
||||
target: arm-unknown-linux-gnueabihf
|
||||
no_run: true
|
||||
- linux:
|
||||
<<: *openssl_102
|
||||
name: armhf-openssl-1.0.2
|
||||
target: arm-unknown-linux-gnueabihf
|
||||
no_run: true
|
||||
- linux:
|
||||
name: x86_64-libressl-2.5
|
||||
target: x86_64-unknown-linux-gnu
|
||||
library: libressl
|
||||
version: 2.5.5
|
||||
- linux:
|
||||
name: x86_64-libressl-3.0.1
|
||||
target: x86_64-unknown-linux-gnu
|
||||
library: libressl
|
||||
version: 3.0.1
|
||||
- macos:
|
||||
name: macos
|
||||
- macos:
|
||||
name: macos-vendored
|
||||
vendored: true
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
[workspace]
|
||||
members = ["openssl", "openssl-sys", "systest"]
|
||||
members = [
|
||||
"openssl",
|
||||
"openssl-errors",
|
||||
"openssl-sys",
|
||||
"systest",
|
||||
]
|
||||
|
||||
176
README.md
176
README.md
@ -1,176 +1,20 @@
|
||||
# rust-openssl
|
||||
|
||||
[](https://circleci.com/gh/sfackler/rust-openssl) [](https://ci.appveyor.com/project/sfackler/rust-openssl/branch/master)
|
||||
[](https://circleci.com/gh/sfackler/rust-openssl)
|
||||
[](https://ci.appveyor.com/project/sfackler/rust-openssl/branch/master)
|
||||
[](https://crates.io/crates/openssl)
|
||||
|
||||
OpenSSL bindings for the Rust programming language.
|
||||
|
||||
[Documentation](https://docs.rs/openssl).
|
||||
|
||||
## Warning
|
||||
## Release Support
|
||||
|
||||
This README does not correspond to rust-openssl 0.7.x or 0.8.x. See
|
||||
[here](https://github.com/sfackler/rust-openssl/blob/b8fb29db5c246175a096260eacca38180cd77dd0/README.md)
|
||||
for that README.
|
||||
The current supported release is 0.10.
|
||||
|
||||
## Building
|
||||
|
||||
rust-openssl depends on OpenSSL version 1.0.1 or above, or LibreSSL. Both the
|
||||
libraries and headers need to be present in the build environment before this
|
||||
crate is compiled, and some instructions of how to do this are in the sections
|
||||
below.
|
||||
|
||||
### Linux
|
||||
|
||||
On Linux, you can typically install OpenSSL via your package manager. The
|
||||
headers are sometimes provided in a separate package than the runtime libraries
|
||||
- look for something like `openssl-devel` or `libssl-dev`. You will also need the
|
||||
regular development utilities, like `pkg-config`, as the custom build script relies
|
||||
on them.
|
||||
|
||||
```bash
|
||||
# On Debian and Ubuntu
|
||||
sudo apt-get install pkg-config libssl-dev
|
||||
# On Arch Linux
|
||||
sudo pacman -S openssl
|
||||
# On Fedora
|
||||
sudo dnf install openssl-devel
|
||||
```
|
||||
|
||||
If installation via a package manager is not possible, or if you're cross
|
||||
compiling to a separate target, you'll typically need to compile OpenSSL from
|
||||
source. That can normally be done with:
|
||||
|
||||
```
|
||||
curl -O https://www.openssl.org/source/openssl-1.1.0f.tar.gz
|
||||
tar xf openssl-1.1.0f.tar.gz
|
||||
cd openssl-1.1.0f
|
||||
export CC=...
|
||||
./Configure --prefix=... linux-x86_64 -fPIC
|
||||
make -j$(nproc)
|
||||
make install
|
||||
```
|
||||
|
||||
### OSX
|
||||
|
||||
Although OpenSSL 0.9.8 is preinstalled on OSX this library is being phased out
|
||||
of OSX and this crate also does not support that version of OpenSSL. To use this
|
||||
crate on OSX you'll need to install OpenSSL via some alternate means, typically
|
||||
Homebrew:
|
||||
|
||||
```bash
|
||||
brew install openssl
|
||||
```
|
||||
|
||||
Occasionally an update of XCode or MacOS will cause the linker to fail after compilation, to rectify this you may want to try and run:
|
||||
|
||||
```bash
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
If Homebrew is installed to the default location of `/usr/local`, OpenSSL will be
|
||||
automatically detected.
|
||||
|
||||
### Windows MSVC
|
||||
|
||||
On MSVC it's unfortunately not always a trivial process acquiring OpenSSL. A couple of possibilities
|
||||
are downloading precompiled binaries for OpenSSL 1.1.0, or installing OpenSSL 1.0.2 using vcpkg.
|
||||
|
||||
#### Installing OpenSSL 1.1.0 using precompiled binaries
|
||||
|
||||
Perhaps the easiest way to do this right now is to download [precompiled
|
||||
binaries] and install them on your system. Currently it's recommended to
|
||||
install the 1.1.0 (non-light) installation if you're choosing this route.
|
||||
|
||||
[precompiled binaries]: http://slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
Once a precompiled binary is installed you can configure this crate to find the
|
||||
installation via an environment variable:
|
||||
|
||||
```
|
||||
set OPENSSL_DIR=C:\OpenSSL-Win64
|
||||
```
|
||||
|
||||
During the installation process if you select "Copy OpenSSL DLLs to: The OpenSSL binaries (/bin)
|
||||
directory", you will need to add them to the `PATH` environment variable:
|
||||
|
||||
```
|
||||
set PATH=%PATH%;C:\OpenSSL-Win64\bin
|
||||
```
|
||||
|
||||
Now you will need to [install root certificates.](#acquiring-root-certificates)
|
||||
|
||||
#### Installing OpenSSL 1.0.2 using vcpkg
|
||||
|
||||
Install [vcpkg](https://github.com/Microsoft/vcpkg), and install the OpenSSL port like this:
|
||||
|
||||
```Batchfile
|
||||
vcpkg install openssl:x64-windows
|
||||
set VCPKG_ROOT=c:\path\to\vcpkg\installation
|
||||
cargo build
|
||||
```
|
||||
|
||||
For more information see the vcpkg build helper [documentation](http://docs.rs/vcpkg).
|
||||
To finsh setting up OpenSSL you will need to [install root certificates.](#acquiring-root-certificates)
|
||||
|
||||
#### Acquiring Root Certificates
|
||||
|
||||
Neither of the above OpenSSL distributions ship with any root certificates.
|
||||
So to make requests to servers on the internet, you have to install them
|
||||
manually. Download the [cacert.pem file from here], copy it somewhere safe
|
||||
(`C:\OpenSSL-Win64\certs` is a good place) and point the `SSL_CERT_FILE`
|
||||
environment variable there:
|
||||
|
||||
```
|
||||
set SSL_CERT_FILE=C:\OpenSSL-Win64\certs\cacert.pem
|
||||
```
|
||||
|
||||
[cacert.pem file from here]: https://curl.haxx.se/docs/caextract.html
|
||||
|
||||
After that, you're just a `cargo build` away!
|
||||
|
||||
### Windows GNU (MinGW)
|
||||
|
||||
The easiest way to acquire OpenSSL when working with MinGW is to ensure you're
|
||||
using [MSYS2](http://msys2.github.io) and to then execute:
|
||||
|
||||
```
|
||||
# 32-bit
|
||||
pacman -S mingw-w64-i686-openssl
|
||||
|
||||
# 64-bit
|
||||
pacman -S mingw-w64-x86_64-openssl
|
||||
```
|
||||
|
||||
And after that, a `cargo build` should be all you need!
|
||||
|
||||
### Manual configuration
|
||||
|
||||
rust-openssl's build script will by default attempt to locate OpenSSL via
|
||||
pkg-config or other system-specific mechanisms. This will not work in some
|
||||
situations however, for example cross compiling or when using a copy of OpenSSL
|
||||
other than the normal system install.
|
||||
|
||||
The build script can be configured via environment variables:
|
||||
|
||||
* `OPENSSL_DIR` - If specified, a directory that will be used to find
|
||||
OpenSSL installation. It's expected that under this directory the `include`
|
||||
folder has header files and a `lib` folder has the runtime libraries.
|
||||
* `OPENSSL_LIB_DIR` - If specified, a directory that will be used to find
|
||||
OpenSSL libraries. Overrides the `lib` folder implied by `OPENSSL_DIR`
|
||||
(if specified).
|
||||
* `OPENSSL_INCLUDE_DIR` - If specified, a directory that will be used to find
|
||||
OpenSSL header files. Overrides the `include` folder implied by `OPENSSL_DIR`
|
||||
(if specified).
|
||||
* `OPENSSL_STATIC` - If specified, OpenSSL libraries will be statically rather
|
||||
than dynamically linked.
|
||||
* `OPENSSL_LIBS` - If specified, the names of the OpenSSL libraries that will be
|
||||
linked, e.g. `ssl:crypto`.
|
||||
|
||||
If `OPENSSL_DIR` or `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` is specified,
|
||||
then the build script will skip the pkg-config step.
|
||||
|
||||
For target-specific configuration, each of these environment variables can be
|
||||
prefixed by an upper-cased target, for example,
|
||||
`X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`. This can be useful in cross compilation
|
||||
contexts.
|
||||
New major versions will be published at most once per year. After a new
|
||||
release, the previous major version will be partially supported with bug
|
||||
fixes for 3 months, after which support will be dropped entirely.
|
||||
|
||||
### Contribution
|
||||
|
||||
|
||||
23
appveyor.yml
23
appveyor.yml
@ -1,25 +1,24 @@
|
||||
environment:
|
||||
SSL_CERT_FILE: "C:\\OpenSSL\\cacert.pem"
|
||||
matrix:
|
||||
# 1.1.0, 64/32 bit
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
BITS: 32
|
||||
MSYS2: 1
|
||||
OPENSSL_VERSION: 1_1_0g
|
||||
# 1.1.1, 64 bit
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
BITS: 64
|
||||
OPENSSL_VERSION: 1_1_0g
|
||||
OPENSSL_VERSION: 1_1_1d
|
||||
OPENSSL_DIR: C:\OpenSSL
|
||||
|
||||
# 1.0.2, 64/32 bit
|
||||
# 1.0.2, 32 bit
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
BITS: 32
|
||||
OPENSSL_VERSION: 1_0_2t
|
||||
OPENSSL_DIR: C:\OpenSSL
|
||||
|
||||
# mingw
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
BITS: 64
|
||||
MSYS2: 1
|
||||
OPENSSL_VERSION: 1_0_2m
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
BITS: 32
|
||||
OPENSSL_VERSION: 1_0_2m
|
||||
OPENSSL_DIR: C:\OpenSSL
|
||||
|
||||
# vcpkg
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows
|
||||
VCPKGRS_DYNAMIC: 1
|
||||
|
||||
9
openssl-errors/CHANGELOG.md
Normal file
9
openssl-errors/CHANGELOG.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Change Log
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## v0.1.0 - 2019-03-14
|
||||
|
||||
Initial release
|
||||
|
||||
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-errors-v0.1.0...master
|
||||
18
openssl-errors/Cargo.toml
Normal file
18
openssl-errors/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "openssl-errors"
|
||||
version = "0.1.0"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Custom error library support for the openssl crate."
|
||||
repository = "https://github.com/sfackler/rust-openssl"
|
||||
readme = "README.md"
|
||||
categories = ["api-bindings"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
openssl-sys = { version = "0.9.42", path = "../openssl-sys" }
|
||||
|
||||
[dev-dependencies]
|
||||
openssl = { version = "0.10.19", path = "../openssl" }
|
||||
202
openssl-errors/LICENSE-APACHE
Normal file
202
openssl-errors/LICENSE-APACHE
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
19
openssl-errors/LICENSE-MIT
Normal file
19
openssl-errors/LICENSE-MIT
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2019 Steven Fackler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1
openssl-errors/README.md
Symbolic link
1
openssl-errors/README.md
Symbolic link
@ -0,0 +1 @@
|
||||
../README.md
|
||||
286
openssl-errors/src/lib.rs
Normal file
286
openssl-errors/src/lib.rs
Normal file
@ -0,0 +1,286 @@
|
||||
//! Custom error library support for the `openssl` crate.
|
||||
//!
|
||||
//! OpenSSL allows third-party libraries to integrate with its error API. This crate provides a safe interface to that.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! use openssl_errors::{openssl_errors, put_error};
|
||||
//! use openssl::error::Error;
|
||||
//!
|
||||
//! // Errors are organized at the top level into "libraries". The
|
||||
//! // openssl_errors! macro can define these.
|
||||
//! //
|
||||
//! // Libraries contain a set of functions and reasons. The library itself,
|
||||
//! // its functions, and its definitions all all have an associated message
|
||||
//! // string. This string is what's shown in OpenSSL errors.
|
||||
//! //
|
||||
//! // The macro creates a type for each library with associated constants for
|
||||
//! // its functions and reasons.
|
||||
//! openssl_errors! {
|
||||
//! pub library MyLib("my cool library") {
|
||||
//! functions {
|
||||
//! FIND_PRIVATE_KEY("find_private_key");
|
||||
//! }
|
||||
//!
|
||||
//! reasons {
|
||||
//! IO_ERROR("IO error");
|
||||
//! BAD_PASSWORD("invalid private key password");
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // The put_error! macro pushes errors onto the OpenSSL error stack.
|
||||
//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::BAD_PASSWORD);
|
||||
//!
|
||||
//! // Prints `error:80001002:my cool library:find_private_key:invalid private key password:src/lib.rs:27:`
|
||||
//! println!("{}", Error::get().unwrap());
|
||||
//!
|
||||
//! // You can also optionally attach an extra string of context using the
|
||||
//! // standard Rust format syntax.
|
||||
//! let tries = 2;
|
||||
//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::IO_ERROR, "tried {} times", tries);
|
||||
//!
|
||||
//! // Prints `error:80001001:my cool library:find_private_key:IO error:src/lib.rs:34:tried 2 times`
|
||||
//! println!("{}", Error::get().unwrap());
|
||||
//! ```
|
||||
#![warn(missing_docs)]
|
||||
#![doc(html_root_url = "https://docs.rs/openssl-errors/0.1")]
|
||||
|
||||
use libc::{c_char, c_int};
|
||||
use std::borrow::Cow;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod export {
|
||||
pub use libc::{c_char, c_int};
|
||||
pub use openssl_sys::{
|
||||
init, ERR_get_next_error_library, ERR_load_strings, ERR_PACK, ERR_STRING_DATA,
|
||||
};
|
||||
pub use std::borrow::Cow;
|
||||
pub use std::option::Option;
|
||||
pub use std::ptr::null;
|
||||
pub use std::sync::Once;
|
||||
}
|
||||
|
||||
/// An OpenSSL error library.
|
||||
pub trait Library {
|
||||
/// Returns the ID assigned to this library by OpenSSL.
|
||||
fn id() -> c_int;
|
||||
}
|
||||
|
||||
/// A function declaration, parameterized by its error library.
|
||||
pub struct Function<T>(c_int, PhantomData<T>);
|
||||
|
||||
impl<T> Function<T> {
|
||||
/// Creates a function from its raw identifier.
|
||||
#[inline]
|
||||
pub const fn from_raw(raw: c_int) -> Function<T> {
|
||||
Function(raw, PhantomData)
|
||||
}
|
||||
|
||||
/// Returns the function's raw identifier.
|
||||
#[inline]
|
||||
pub const fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// A reason declaration, parameterized by its error library.
|
||||
pub struct Reason<T>(c_int, PhantomData<T>);
|
||||
|
||||
impl<T> Reason<T> {
|
||||
/// Creates a reason from its raw identifier.
|
||||
#[inline]
|
||||
pub const fn from_raw(raw: c_int) -> Reason<T> {
|
||||
Reason(raw, PhantomData)
|
||||
}
|
||||
|
||||
/// Returns the reason's raw identifier.
|
||||
#[inline]
|
||||
pub const fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not considered part of this crate's public API. It is subject to change at any time.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `file` and `message` must be null-terminated.
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn __put_error<T>(
|
||||
func: Function<T>,
|
||||
reason: Reason<T>,
|
||||
file: &'static str,
|
||||
line: u32,
|
||||
message: Option<Cow<'static, str>>,
|
||||
) where
|
||||
T: Library,
|
||||
{
|
||||
openssl_sys::ERR_put_error(
|
||||
T::id(),
|
||||
func.as_raw(),
|
||||
reason.as_raw(),
|
||||
file.as_ptr() as *const c_char,
|
||||
line as c_int,
|
||||
);
|
||||
let data = match message {
|
||||
Some(Cow::Borrowed(s)) => Some((s.as_ptr() as *const c_char as *mut c_char, 0)),
|
||||
Some(Cow::Owned(s)) => {
|
||||
let ptr = openssl_sys::CRYPTO_malloc(
|
||||
s.len() as _,
|
||||
concat!(file!(), "\0").as_ptr() as *const c_char,
|
||||
line!() as c_int,
|
||||
) as *mut c_char;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
ptr::copy_nonoverlapping(s.as_ptr(), ptr as *mut u8, s.len());
|
||||
Some((ptr, openssl_sys::ERR_TXT_MALLOCED))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
if let Some((ptr, flags)) = data {
|
||||
openssl_sys::ERR_set_error_data(ptr, flags | openssl_sys::ERR_TXT_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes an error onto the OpenSSL error stack.
|
||||
///
|
||||
/// A function and reason are required, and must be associated with the same error library. An additional formatted
|
||||
/// message string can also optionally be provided.
|
||||
#[macro_export]
|
||||
macro_rules! put_error {
|
||||
($function:expr, $reason:expr) => {
|
||||
unsafe {
|
||||
$crate::__put_error(
|
||||
$function,
|
||||
$reason,
|
||||
concat!(file!(), "\0"),
|
||||
line!(),
|
||||
$crate::export::Option::None,
|
||||
);
|
||||
}
|
||||
};
|
||||
($function:expr, $reason:expr, $message:expr) => {
|
||||
unsafe {
|
||||
$crate::__put_error(
|
||||
$function,
|
||||
$reason,
|
||||
concat!(file!(), "\0"),
|
||||
line!(),
|
||||
$crate::export::Option::Some($crate::export::Cow::Borrowed(
|
||||
concat!($message, "\0"),
|
||||
)),
|
||||
);
|
||||
}
|
||||
};
|
||||
($function:expr, $reason:expr, $message:expr, $($args:tt)*) => {
|
||||
unsafe {
|
||||
$crate::__put_error(
|
||||
$function,
|
||||
$reason,
|
||||
concat!(file!(), "\0"),
|
||||
line!(),
|
||||
$crate::export::Option::Some($crate::export::Cow::Owned(
|
||||
format!(concat!($message, "\0"), $($args)*)),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Defines custom OpenSSL error libraries.
|
||||
///
|
||||
/// The created libraries can be used with the `put_error!` macro to create custom OpenSSL errors.
|
||||
#[macro_export]
|
||||
macro_rules! openssl_errors {
|
||||
($(
|
||||
$(#[$lib_attr:meta])*
|
||||
$lib_vis:vis library $lib_name:ident($lib_str:expr) {
|
||||
functions {
|
||||
$(
|
||||
$(#[$func_attr:meta])*
|
||||
$func_name:ident($func_str:expr);
|
||||
)*
|
||||
}
|
||||
|
||||
reasons {
|
||||
$(
|
||||
$(#[$reason_attr:meta])*
|
||||
$reason_name:ident($reason_str:expr);
|
||||
)*
|
||||
}
|
||||
}
|
||||
)*) => {$(
|
||||
$(#[$lib_attr])*
|
||||
$lib_vis enum $lib_name {}
|
||||
|
||||
impl $crate::Library for $lib_name {
|
||||
fn id() -> $crate::export::c_int {
|
||||
static INIT: $crate::export::Once = $crate::export::Once::new();
|
||||
static mut LIB_NUM: $crate::export::c_int = 0;
|
||||
static mut STRINGS: [
|
||||
$crate::export::ERR_STRING_DATA;
|
||||
2 + $crate::openssl_errors!(@count $($func_name;)* $($reason_name;)*)
|
||||
] = [
|
||||
$crate::export::ERR_STRING_DATA {
|
||||
error: 0,
|
||||
string: concat!($lib_str, "\0").as_ptr() as *const $crate::export::c_char,
|
||||
},
|
||||
$(
|
||||
$crate::export::ERR_STRING_DATA {
|
||||
error: $crate::export::ERR_PACK(0, $lib_name::$func_name.as_raw(), 0),
|
||||
string: concat!($func_str, "\0").as_ptr() as *const $crate::export::c_char,
|
||||
},
|
||||
)*
|
||||
$(
|
||||
$crate::export::ERR_STRING_DATA {
|
||||
error: $crate::export::ERR_PACK(0, 0, $lib_name::$reason_name.as_raw()),
|
||||
string: concat!($reason_str, "\0").as_ptr() as *const $crate::export::c_char,
|
||||
},
|
||||
)*
|
||||
$crate::export::ERR_STRING_DATA {
|
||||
error: 0,
|
||||
string: $crate::export::null(),
|
||||
}
|
||||
];
|
||||
|
||||
unsafe {
|
||||
INIT.call_once(|| {
|
||||
$crate::export::init();
|
||||
LIB_NUM = $crate::export::ERR_get_next_error_library();
|
||||
STRINGS[0].error = $crate::export::ERR_PACK(LIB_NUM, 0, 0);
|
||||
$crate::export::ERR_load_strings(LIB_NUM, STRINGS.as_mut_ptr());
|
||||
});
|
||||
|
||||
LIB_NUM
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $lib_name {
|
||||
$crate::openssl_errors!(@func_consts $lib_name; 1; $($(#[$func_attr])* $func_name;)*);
|
||||
$crate::openssl_errors!(@reason_consts $lib_name; 1; $($(#[$reason_attr])* $reason_name;)*);
|
||||
}
|
||||
)*};
|
||||
(@func_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => {
|
||||
$(#[$attr])*
|
||||
pub const $name: $crate::Function<$lib_name> = $crate::Function::from_raw($n);
|
||||
$crate::openssl_errors!(@func_consts $lib_name; $n + 1; $($tt)*);
|
||||
};
|
||||
(@func_consts $lib_name:ident; $n:expr;) => {};
|
||||
(@reason_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => {
|
||||
$(#[$attr])*
|
||||
pub const $name: $crate::Reason<$lib_name> = $crate::Reason::from_raw($n);
|
||||
$crate::openssl_errors!(@reason_consts $lib_name; $n + 1; $($tt)*);
|
||||
};
|
||||
(@reason_consts $lib_name:ident; $n:expr;) => {};
|
||||
(@count $i:ident; $($tt:tt)*) => {
|
||||
1 + $crate::openssl_errors!(@count $($tt)*)
|
||||
};
|
||||
(@count) => { 0 };
|
||||
}
|
||||
54
openssl-errors/tests/test.rs
Normal file
54
openssl-errors/tests/test.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use openssl::error::Error;
|
||||
|
||||
openssl_errors::openssl_errors! {
|
||||
library Test("test library") {
|
||||
functions {
|
||||
FOO("function foo");
|
||||
BAR("function bar");
|
||||
}
|
||||
|
||||
reasons {
|
||||
NO_MILK("out of milk");
|
||||
NO_BACON("out of bacon");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic() {
|
||||
openssl_errors::put_error!(Test::FOO, Test::NO_MILK);
|
||||
|
||||
let error = Error::get().unwrap();
|
||||
assert_eq!(error.library().unwrap(), "test library");
|
||||
assert_eq!(error.function().unwrap(), "function foo");
|
||||
assert_eq!(error.reason().unwrap(), "out of milk");
|
||||
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
|
||||
assert_eq!(error.line(), 19);
|
||||
assert_eq!(error.data(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn static_data() {
|
||||
openssl_errors::put_error!(Test::BAR, Test::NO_BACON, "foobar");
|
||||
|
||||
let error = Error::get().unwrap();
|
||||
assert_eq!(error.library().unwrap(), "test library");
|
||||
assert_eq!(error.function().unwrap(), "function bar");
|
||||
assert_eq!(error.reason().unwrap(), "out of bacon");
|
||||
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
|
||||
assert_eq!(error.line(), 32);
|
||||
assert_eq!(error.data(), Some("foobar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dynamic_data() {
|
||||
openssl_errors::put_error!(Test::BAR, Test::NO_MILK, "hello {}", "world");
|
||||
|
||||
let error = Error::get().unwrap();
|
||||
assert_eq!(error.library().unwrap(), "test library");
|
||||
assert_eq!(error.function().unwrap(), "function bar");
|
||||
assert_eq!(error.reason().unwrap(), "out of milk");
|
||||
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
|
||||
assert_eq!(error.line(), 45);
|
||||
assert_eq!(error.data(), Some("hello world"));
|
||||
}
|
||||
76
openssl-sys/CHANGELOG.md
Normal file
76
openssl-sys/CHANGELOG.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Change Log
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.9.50] - 2019-10-02
|
||||
|
||||
### Added
|
||||
|
||||
* Added `CRYPTO_LOCK_EVP_PKEY`.
|
||||
* Added `EVP_PKEY_ED25519` and `EVP_PKEY_ED448`.
|
||||
* Added `EVP_DigestSign` and `EVP_DigestVerify`.
|
||||
* Added `EVP_PKEY_up_ref`.
|
||||
* Added `NID_ED25519` and `NID_ED448`.
|
||||
|
||||
## [v0.9.49] - 2019-08-15
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for LibreSSL 3.0.0.
|
||||
|
||||
## [v0.9.48] - 2019-07-19
|
||||
|
||||
### Added
|
||||
|
||||
* Added `AES_wrap_key` and `AES_unwrap_key`.
|
||||
* Added `EC_GROUP_get_cofactor`, `EC_GROUP_get0_generator`, and `EC_POINT_dup`.
|
||||
* Added `EVP_aes_128_ofb`, `EVP_aes_192_ecb`, `EVP_aes_192_cbc`, `EVP_aes_192_cfb1`, `EVP_aes_192_cfb8`,
|
||||
`EVP_aes_192_cfb_128`, `EVP_aes_192_ctr`, `EVP_aes_192_ccm`, `EVP_aes_192_gcm`, `EVP_aes_192_ofb`, and
|
||||
`EVP_aes_256_ofb`.
|
||||
* Added `PEM_read_bio_CMS` and `PEM_write_bio_CMS`.
|
||||
|
||||
## [v0.9.47] - 2019-05-18
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SSL_CTX_add_client_CA`.
|
||||
|
||||
## [v0.9.46] - 2019-05-08
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for the LibreSSL 2.9.x series.
|
||||
|
||||
## [v0.9.45] - 2019-05-03
|
||||
|
||||
### Fixed
|
||||
|
||||
* Reverted a change to windows-gnu library names that caused regressions.
|
||||
|
||||
## [v0.9.44] - 2019-04-30
|
||||
|
||||
### Added
|
||||
|
||||
* The `DEP_OPENSSL_VENDORED` environment variable tells downstream build scripts if the vendored feature was enabled.
|
||||
* Added `EVP_SealInit`, `EVP_SealFinal`, `EVP_EncryptUpdate`, `EVP_OpenInit`, `EVP_OpenFinal`, and `EVP_DecryptUpdate`.
|
||||
* Added `EVP_PKEY_size`.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed library names when targeting windows-gnu and pkg-config fails.
|
||||
|
||||
## [v0.9.43] - 2019-03-20
|
||||
|
||||
### Added
|
||||
|
||||
* Added `d2i_CMS_ContentInfo` and `CMS_encrypt`.
|
||||
* Added `X509_verify` and `X509_REQ_verify`.
|
||||
* Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`.
|
||||
|
||||
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.48...master
|
||||
[v0.9.47]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.47...openssl-sys-v0.9.48
|
||||
[v0.9.47]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.46...openssl-sys-v0.9.47
|
||||
[v0.9.46]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.45...openssl-sys-v0.9.46
|
||||
[v0.9.45]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.44...openssl-sys-v0.9.45
|
||||
[v0.9.44]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.43...openssl-sys-v0.9.44
|
||||
[v0.9.43]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.42...openssl-sys-v0.9.43
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.23"
|
||||
version = "0.9.50"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>",
|
||||
"Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "MIT"
|
||||
@ -9,14 +9,19 @@ repository = "https://github.com/sfackler/rust-openssl"
|
||||
readme = "README.md"
|
||||
categories = ["cryptography", "external-ffi-bindings"]
|
||||
links = "openssl"
|
||||
build = "build.rs"
|
||||
build = "build/main.rs"
|
||||
|
||||
[features]
|
||||
vendored = ['openssl-src']
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
pkg-config = "0.3.9"
|
||||
cc = "1.0"
|
||||
openssl-src = { version = "111.0.1", optional = true }
|
||||
pkg-config = "0.3.9"
|
||||
autocfg = "0.1.2"
|
||||
|
||||
[target.'cfg(target_env = "msvc")'.build-dependencies]
|
||||
vcpkg = "0.2"
|
||||
|
||||
@ -1,543 +0,0 @@
|
||||
extern crate pkg_config;
|
||||
#[cfg(target_env = "msvc")]
|
||||
extern crate vcpkg;
|
||||
extern crate cc;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::panic::{self, AssertUnwindSafe};
|
||||
use std::process::Command;
|
||||
|
||||
// The set of `OPENSSL_NO_<FOO>`s that we care about.
|
||||
const DEFINES: &'static [&'static str] = &[
|
||||
"OPENSSL_NO_BUF_FREELISTS",
|
||||
"OPENSSL_NO_COMP",
|
||||
"OPENSSL_NO_EC",
|
||||
"OPENSSL_NO_EC2M",
|
||||
"OPENSSL_NO_ENGINE",
|
||||
"OPENSSL_NO_KRB5",
|
||||
"OPENSSL_NO_NEXTPROTONEG",
|
||||
"OPENSSL_NO_PSK",
|
||||
"OPENSSL_NO_RFC3779",
|
||||
"OPENSSL_NO_SHA",
|
||||
"OPENSSL_NO_SRP",
|
||||
"OPENSSL_NO_SSL3_METHOD",
|
||||
"OPENSSL_NO_TLSEXT",
|
||||
];
|
||||
|
||||
enum Version {
|
||||
Openssl110,
|
||||
Openssl102,
|
||||
Openssl101,
|
||||
Libressl,
|
||||
}
|
||||
|
||||
fn env(name: &str) -> Option<OsString> {
|
||||
let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_");
|
||||
let prefixed = format!("{}_{}", prefix, name);
|
||||
println!("cargo:rerun-if-env-changed={}", prefixed);
|
||||
|
||||
if let Some(var) = env::var_os(&prefixed) {
|
||||
return Some(var);
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-env-changed={}", name);
|
||||
env::var_os(name)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
||||
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
|
||||
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
|
||||
|
||||
let (lib_dir, include_dir) = if lib_dir.is_none() || include_dir.is_none() {
|
||||
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target));
|
||||
let openssl_dir = Path::new(&openssl_dir);
|
||||
let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib"));
|
||||
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
|
||||
(lib_dir, include_dir)
|
||||
} else {
|
||||
(lib_dir.unwrap(), include_dir.unwrap())
|
||||
};
|
||||
|
||||
if !Path::new(&lib_dir).exists() {
|
||||
panic!(
|
||||
"OpenSSL library directory does not exist: {}",
|
||||
lib_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
if !Path::new(&include_dir).exists() {
|
||||
panic!(
|
||||
"OpenSSL include directory does not exist: {}",
|
||||
include_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
lib_dir.to_string_lossy()
|
||||
);
|
||||
println!("cargo:include={}", include_dir.to_string_lossy());
|
||||
|
||||
let version = validate_headers(&[include_dir.clone().into()]);
|
||||
|
||||
let libs_env = env("OPENSSL_LIBS");
|
||||
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
|
||||
Some(ref v) => v.split(":").collect(),
|
||||
None => {
|
||||
match version {
|
||||
Version::Openssl101 |
|
||||
Version::Openssl102 if target.contains("windows") => vec!["ssleay32", "libeay32"],
|
||||
Version::Openssl110 if target.contains("windows") => vec!["libssl", "libcrypto"],
|
||||
_ => vec!["ssl", "crypto"],
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let kind = determine_mode(Path::new(&lib_dir), &libs);
|
||||
for lib in libs.into_iter() {
|
||||
println!("cargo:rustc-link-lib={}={}", kind, lib);
|
||||
}
|
||||
}
|
||||
|
||||
fn find_openssl_dir(target: &str) -> OsString {
|
||||
let host = env::var("HOST").unwrap();
|
||||
|
||||
if host.contains("apple-darwin") && target.contains("apple-darwin") {
|
||||
let homebrew = Path::new("/usr/local/opt/openssl@1.1");
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
let homebrew = Path::new("/usr/local/opt/openssl");
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
}
|
||||
|
||||
try_pkg_config();
|
||||
try_vcpkg();
|
||||
|
||||
let mut msg = format!(
|
||||
"
|
||||
|
||||
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
|
||||
proceed without this knowledge. If OpenSSL is installed and this crate had
|
||||
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
|
||||
compilation process.
|
||||
|
||||
If you're in a situation where you think the directory *should* be found
|
||||
automatically, please open a bug at https://github.com/sfackler/rust-openssl
|
||||
and include information about your system as well as this message.
|
||||
|
||||
$HOST = {}
|
||||
$TARGET = {}
|
||||
openssl-sys = {}
|
||||
|
||||
",
|
||||
host,
|
||||
target,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
|
||||
if host.contains("apple-darwin") && target.contains("apple-darwin") {
|
||||
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
|
||||
if system.exists() {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
|
||||
It looks like you're compiling on macOS, where the system contains a version of
|
||||
OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8.
|
||||
|
||||
As a consumer of this crate, you can fix this error by using Homebrew to
|
||||
install the `openssl` package, or as a maintainer you can use the openssl-sys
|
||||
0.7 crate for support with OpenSSL 0.9.8.
|
||||
|
||||
Unfortunately though the compile cannot continue, so aborting.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") {
|
||||
if Command::new("pkg-config").output().is_err() {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling on Linux and also targeting Linux. Currently this
|
||||
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
|
||||
could not be found. If you have OpenSSL installed you can likely fix this by
|
||||
installing `pkg-config`.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if host.contains("windows") && target.contains("windows-gnu") {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling for MinGW but you may not have either OpenSSL or
|
||||
pkg-config installed. You can install these two dependencies with:
|
||||
|
||||
pacman -S openssl-devel pkg-config
|
||||
|
||||
and try building this crate again.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
|
||||
if host.contains("windows") && target.contains("windows-msvc") {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
|
||||
installation. If there isn't one installed then you can try the rust-openssl
|
||||
README for more information about how to download precompiled binaries of
|
||||
OpenSSL:
|
||||
|
||||
https://github.com/sfackler/rust-openssl#windows
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
|
||||
panic!(msg);
|
||||
}
|
||||
|
||||
/// Attempt to find OpenSSL through pkg-config.
|
||||
///
|
||||
/// Note that if this succeeds then the function does not return as pkg-config
|
||||
/// typically tells us all the information that we need.
|
||||
fn try_pkg_config() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let host = env::var("HOST").unwrap();
|
||||
|
||||
// If we're going to windows-gnu we can use pkg-config, but only so long as
|
||||
// we're coming from a windows host.
|
||||
//
|
||||
// Otherwise if we're going to windows we probably can't use pkg-config.
|
||||
if target.contains("windows-gnu") && host.contains("windows") {
|
||||
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
|
||||
} else if target.contains("windows") {
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = match pkg_config::Config::new().print_system_libs(false).find(
|
||||
"openssl",
|
||||
) {
|
||||
Ok(lib) => lib,
|
||||
Err(e) => {
|
||||
println!("run pkg_config fail: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
validate_headers(&lib.include_paths);
|
||||
|
||||
for include in lib.include_paths.iter() {
|
||||
println!("cargo:include={}", include.display());
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
/// Attempt to find OpenSSL through vcpkg.
|
||||
///
|
||||
/// Note that if this succeeds then the function does not return as vcpkg
|
||||
/// should emit all of the cargo metadata that we need.
|
||||
#[cfg(target_env = "msvc")]
|
||||
fn try_vcpkg() {
|
||||
|
||||
// vcpkg will not emit any metadata if it can not find libraries
|
||||
// appropriate for the target triple with the desired linkage.
|
||||
|
||||
let mut lib = vcpkg::Config::new()
|
||||
.emit_includes(true)
|
||||
.lib_name("libcrypto")
|
||||
.lib_name("libssl")
|
||||
.probe("openssl");
|
||||
|
||||
if let Err(e) = lib {
|
||||
println!("note: vcpkg did not find openssl as libcrypto and libssl : {:?}",
|
||||
e);
|
||||
lib = vcpkg::Config::new()
|
||||
.emit_includes(true)
|
||||
.lib_name("libeay32")
|
||||
.lib_name("ssleay32")
|
||||
.probe("openssl");
|
||||
}
|
||||
if let Err(e) = lib {
|
||||
println!("note: vcpkg did not find openssl as ssleay32 and libeay32: {:?}",
|
||||
e);
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = lib.unwrap();
|
||||
validate_headers(&lib.include_paths);
|
||||
|
||||
println!("cargo:rustc-link-lib=user32");
|
||||
println!("cargo:rustc-link-lib=gdi32");
|
||||
println!("cargo:rustc-link-lib=crypt32");
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
#[cfg(not(target_env = "msvc"))]
|
||||
fn try_vcpkg() {}
|
||||
|
||||
/// Validates the header files found in `include_dir` and then returns the
|
||||
/// version string of OpenSSL.
|
||||
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
|
||||
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
|
||||
// correctly expose the right API from this crate, take a look at
|
||||
// `opensslv.h` to see what version OpenSSL claims to be.
|
||||
//
|
||||
// OpenSSL has a number of build-time configuration options which affect
|
||||
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
|
||||
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
|
||||
//
|
||||
// To handle all this conditional compilation we slurp up the configuration
|
||||
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
|
||||
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
|
||||
// account for compile differences and such.
|
||||
let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
path.push("expando.c");
|
||||
let mut file = BufWriter::new(File::create(&path).unwrap());
|
||||
|
||||
write!(
|
||||
file,
|
||||
"\
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#if LIBRESSL_VERSION_NUMBER >= 0x20700000
|
||||
RUST_LIBRESSL_NEW
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20603000
|
||||
RUST_LIBRESSL_26X
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20602000
|
||||
RUST_LIBRESSL_262
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20601000
|
||||
RUST_LIBRESSL_261
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20600000
|
||||
RUST_LIBRESSL_260
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20503000
|
||||
RUST_LIBRESSL_25X
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20502000
|
||||
RUST_LIBRESSL_252
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20501000
|
||||
RUST_LIBRESSL_251
|
||||
#elif LIBRESSL_VERSION_NUMBER >= 0x20500000
|
||||
RUST_LIBRESSL_250
|
||||
#elif defined (LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20500000
|
||||
RUST_LIBRESSL_OLD
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10101000
|
||||
RUST_OPENSSL_NEW
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10100060
|
||||
RUST_OPENSSL_110F
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10100000
|
||||
RUST_OPENSSL_110
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10002000
|
||||
RUST_OPENSSL_102
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
RUST_OPENSSL_101
|
||||
#else
|
||||
RUST_OPENSSL_OLD
|
||||
#endif
|
||||
"
|
||||
).unwrap();
|
||||
|
||||
for define in DEFINES {
|
||||
write!(
|
||||
file,
|
||||
"\
|
||||
#ifdef {define}
|
||||
RUST_{define}_RUST
|
||||
#endif
|
||||
",
|
||||
define = define
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
file.flush().unwrap();
|
||||
drop(file);
|
||||
|
||||
let mut gcc = cc::Build::new();
|
||||
for include_dir in include_dirs {
|
||||
gcc.include(include_dir);
|
||||
}
|
||||
// https://github.com/alexcrichton/gcc-rs/issues/133
|
||||
let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) {
|
||||
Ok(expanded) => expanded,
|
||||
Err(_) => {
|
||||
panic!(
|
||||
"
|
||||
Failed to find OpenSSL development headers.
|
||||
|
||||
You can try fixing this setting the `OPENSSL_DIR` environment variable
|
||||
pointing to your OpenSSL installation or installing OpenSSL headers package
|
||||
specific to your distribution:
|
||||
|
||||
# On Ubuntu
|
||||
sudo apt-get install libssl-dev
|
||||
# On Arch Linux
|
||||
sudo pacman -S openssl
|
||||
# On Fedora
|
||||
sudo dnf install openssl-devel
|
||||
|
||||
See rust-openssl README for more information:
|
||||
|
||||
https://github.com/sfackler/rust-openssl#linux
|
||||
"
|
||||
);
|
||||
}
|
||||
};
|
||||
let expanded = String::from_utf8(expanded).unwrap();
|
||||
|
||||
let mut enabled = vec![];
|
||||
for &define in DEFINES {
|
||||
if expanded.contains(&format!("RUST_{}_RUST", define)) {
|
||||
println!("cargo:rustc-cfg=osslconf=\"{}\"", define);
|
||||
enabled.push(define);
|
||||
}
|
||||
}
|
||||
println!("cargo:conf={}", enabled.join(","));
|
||||
|
||||
if expanded.contains("RUST_LIBRESSL_250") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl250");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=250");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_251") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl251");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=251");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_252") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl252");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=252");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_25X") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl25x");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=25x");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_260") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl260");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=260");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_261") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl261");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=261");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_262") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl262");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=262");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_LIBRESSL_26X") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl26x");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=26x");
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_OPENSSL_110F") {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:rustc-cfg=ossl110f");
|
||||
println!("cargo:version=110");
|
||||
println!("cargo:patch=f");
|
||||
Version::Openssl110
|
||||
} else if expanded.contains("RUST_OPENSSL_110") {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:version=110");
|
||||
Version::Openssl110
|
||||
} else if expanded.contains("RUST_OPENSSL_102") {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:version=102");
|
||||
Version::Openssl102
|
||||
} else if expanded.contains("RUST_OPENSSL_101") {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
println!("cargo:version=101");
|
||||
Version::Openssl101
|
||||
} else {
|
||||
panic!(
|
||||
"
|
||||
|
||||
This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL
|
||||
2.5 and 2.6.0, but a different version of OpenSSL was found. The build is now
|
||||
aborting due to this version mismatch.
|
||||
|
||||
"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
|
||||
/// of the libraries we're linking to, figure out whether we should link them
|
||||
/// statically or dynamically.
|
||||
fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
|
||||
// First see if a mode was explicitly requested
|
||||
let kind = env("OPENSSL_STATIC");
|
||||
match kind.as_ref().and_then(|s| s.to_str()).map(|s| &s[..]) {
|
||||
Some("0") => return "dylib",
|
||||
Some(_) => return "static",
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Next, see what files we actually have to link against, and see what our
|
||||
// possibilities even are.
|
||||
let files = libdir
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap())
|
||||
.map(|e| e.file_name())
|
||||
.filter_map(|e| e.into_string().ok())
|
||||
.collect::<HashSet<_>>();
|
||||
let can_static = libs.iter().all(|l| {
|
||||
files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))
|
||||
});
|
||||
let can_dylib = libs.iter().all(|l| {
|
||||
files.contains(&format!("lib{}.so", l)) || files.contains(&format!("{}.dll", l)) ||
|
||||
files.contains(&format!("lib{}.dylib", l))
|
||||
});
|
||||
match (can_static, can_dylib) {
|
||||
(true, false) => return "static",
|
||||
(false, true) => return "dylib",
|
||||
(false, false) => {
|
||||
panic!(
|
||||
"OpenSSL libdir at `{}` does not contain the required files \
|
||||
to either statically or dynamically link OpenSSL",
|
||||
libdir.display()
|
||||
);
|
||||
}
|
||||
(true, true) => {}
|
||||
}
|
||||
|
||||
// Ok, we've got not explicit preference and can *either* link statically or
|
||||
// link dynamically. In the interest of "security upgrades" and/or "best
|
||||
// practices with security libs", let's link dynamically.
|
||||
"dylib"
|
||||
}
|
||||
67
openssl-sys/build/cfgs.rs
Normal file
67
openssl-sys/build/cfgs.rs
Normal file
@ -0,0 +1,67 @@
|
||||
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
|
||||
let mut cfgs = vec![];
|
||||
|
||||
if let Some(libressl_version) = libressl_version {
|
||||
cfgs.push("libressl");
|
||||
|
||||
if libressl_version >= 0x2_05_01_00_0 {
|
||||
cfgs.push("libressl251");
|
||||
}
|
||||
if libressl_version >= 0x2_06_01_00_0 {
|
||||
cfgs.push("libressl261");
|
||||
}
|
||||
if libressl_version >= 0x2_07_00_00_0 {
|
||||
cfgs.push("libressl270");
|
||||
}
|
||||
if libressl_version >= 0x2_07_01_00_0 {
|
||||
cfgs.push("libressl271");
|
||||
}
|
||||
if libressl_version >= 0x2_07_03_00_0 {
|
||||
cfgs.push("libressl273");
|
||||
}
|
||||
if libressl_version >= 0x2_08_00_00_0 {
|
||||
cfgs.push("libressl280");
|
||||
}
|
||||
if libressl_version >= 0x2_08_01_00_0 {
|
||||
cfgs.push("libressl281");
|
||||
}
|
||||
if libressl_version >= 0x2_09_01_00_0 {
|
||||
cfgs.push("libressl291");
|
||||
}
|
||||
} else {
|
||||
let openssl_version = openssl_version.unwrap();
|
||||
|
||||
if openssl_version >= 0x1_00_01_00_0 {
|
||||
cfgs.push("ossl101");
|
||||
}
|
||||
if openssl_version >= 0x1_00_02_00_0 {
|
||||
cfgs.push("ossl102");
|
||||
}
|
||||
if openssl_version >= 0x1_00_02_06_0 {
|
||||
cfgs.push("ossl102f");
|
||||
}
|
||||
if openssl_version >= 0x1_00_02_08_0 {
|
||||
cfgs.push("ossl102h");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_00_0 {
|
||||
cfgs.push("ossl110");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_06_0 {
|
||||
cfgs.push("ossl110f");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_07_0 {
|
||||
cfgs.push("ossl110g");
|
||||
}
|
||||
if openssl_version >= 0x1_01_01_00_0 {
|
||||
cfgs.push("ossl111");
|
||||
}
|
||||
if openssl_version >= 0x1_01_01_02_0 {
|
||||
cfgs.push("ossl111b");
|
||||
}
|
||||
if openssl_version >= 0x1_01_01_03_0 {
|
||||
cfgs.push("ossl111c");
|
||||
}
|
||||
}
|
||||
|
||||
cfgs
|
||||
}
|
||||
67
openssl-sys/build/expando.c
Normal file
67
openssl-sys/build/expando.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#define VERSION2(n, v) RUST_VERSION_##n##_##v
|
||||
#define VERSION(n, v) VERSION2(n, v)
|
||||
|
||||
#ifdef LIBRESSL_VERSION_NUMBER
|
||||
VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
|
||||
#else
|
||||
VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_BUF_FREELISTS
|
||||
RUST_CONF_OPENSSL_NO_BUF_FREELISTS
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_COMP
|
||||
RUST_CONF_OPENSSL_NO_COMP
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_EC
|
||||
RUST_CONF_OPENSSL_NO_EC
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
RUST_CONF_OPENSSL_NO_EC2M
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_ENGINE
|
||||
RUST_CONF_OPENSSL_NO_ENGINE
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_KRB5
|
||||
RUST_CONF_OPENSSL_NO_KRB5
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_NEXTPROTONEG
|
||||
RUST_CONF_OPENSSL_NO_NEXTPROTONEG
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_PSK
|
||||
RUST_CONF_OPENSSL_NO_PSK
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_RFC3779
|
||||
RUST_CONF_OPENSSL_NO_RFC3779
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_SHA
|
||||
RUST_CONF_OPENSSL_NO_SHA
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_SRP
|
||||
RUST_CONF_OPENSSL_NO_SRP
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_SSL3_METHOD
|
||||
RUST_CONF_OPENSSL_NO_SSL3_METHOD
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_TLSEXT
|
||||
RUST_CONF_OPENSSL_NO_TLSEXT
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_STDIO
|
||||
RUST_CONF_OPENSSL_NO_STDIO
|
||||
#endif
|
||||
251
openssl-sys/build/find_normal.rs
Normal file
251
openssl-sys/build/find_normal.rs
Normal file
@ -0,0 +1,251 @@
|
||||
use pkg_config;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command};
|
||||
|
||||
use super::env;
|
||||
|
||||
pub fn get_openssl(target: &str) -> (PathBuf, PathBuf) {
|
||||
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
|
||||
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
|
||||
|
||||
if lib_dir.is_none() || include_dir.is_none() {
|
||||
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target));
|
||||
let openssl_dir = Path::new(&openssl_dir);
|
||||
let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib"));
|
||||
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
|
||||
(lib_dir, include_dir)
|
||||
} else {
|
||||
(lib_dir.unwrap(), include_dir.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
fn find_openssl_dir(target: &str) -> OsString {
|
||||
let host = env::var("HOST").unwrap();
|
||||
|
||||
if host == target && target.contains("apple-darwin") {
|
||||
// Check up default Homebrew installation location first
|
||||
// for quick resolution if possible.
|
||||
let homebrew = Path::new("/usr/local/opt/openssl@1.1");
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
let homebrew = Path::new("/usr/local/opt/openssl");
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
// Calling `brew --prefix <package>` command usually slow and
|
||||
// takes seconds, and will be used only as a last resort.
|
||||
let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]);
|
||||
if let Some(ref output) = output {
|
||||
let homebrew = Path::new(&output);
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
}
|
||||
let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]);
|
||||
if let Some(ref output) = output {
|
||||
let homebrew = Path::new(&output);
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try_pkg_config();
|
||||
try_vcpkg();
|
||||
|
||||
// FreeBSD ships with OpenSSL but doesn't include a pkg-config file :(
|
||||
if host == target && target.contains("freebsd") {
|
||||
return OsString::from("/usr");
|
||||
}
|
||||
|
||||
let mut msg = format!(
|
||||
"
|
||||
|
||||
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
|
||||
proceed without this knowledge. If OpenSSL is installed and this crate had
|
||||
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
|
||||
compilation process.
|
||||
|
||||
Make sure you also have the development packages of openssl installed.
|
||||
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
|
||||
|
||||
If you're in a situation where you think the directory *should* be found
|
||||
automatically, please open a bug at https://github.com/sfackler/rust-openssl
|
||||
and include information about your system as well as this message.
|
||||
|
||||
$HOST = {}
|
||||
$TARGET = {}
|
||||
openssl-sys = {}
|
||||
|
||||
",
|
||||
host,
|
||||
target,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
|
||||
if host.contains("apple-darwin") && target.contains("apple-darwin") {
|
||||
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
|
||||
if system.exists() {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
|
||||
It looks like you're compiling on macOS, where the system contains a version of
|
||||
OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8.
|
||||
|
||||
As a consumer of this crate, you can fix this error by using Homebrew to
|
||||
install the `openssl` package, or as a maintainer you can use the openssl-sys
|
||||
0.7 crate for support with OpenSSL 0.9.8.
|
||||
|
||||
Unfortunately though the compile cannot continue, so aborting.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") {
|
||||
if Command::new("pkg-config").output().is_err() {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling on Linux and also targeting Linux. Currently this
|
||||
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
|
||||
could not be found. If you have OpenSSL installed you can likely fix this by
|
||||
installing `pkg-config`.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if host.contains("windows") && target.contains("windows-gnu") {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling for MinGW but you may not have either OpenSSL or
|
||||
pkg-config installed. You can install these two dependencies with:
|
||||
|
||||
pacman -S openssl-devel pkg-config
|
||||
|
||||
and try building this crate again.
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
|
||||
if host.contains("windows") && target.contains("windows-msvc") {
|
||||
msg.push_str(&format!(
|
||||
"
|
||||
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
|
||||
installation. If there isn't one installed then you can try the rust-openssl
|
||||
README for more information about how to download precompiled binaries of
|
||||
OpenSSL:
|
||||
|
||||
https://github.com/sfackler/rust-openssl#windows
|
||||
|
||||
"
|
||||
));
|
||||
}
|
||||
|
||||
panic!(msg);
|
||||
}
|
||||
|
||||
/// Attempt to find OpenSSL through pkg-config.
|
||||
///
|
||||
/// Note that if this succeeds then the function does not return as pkg-config
|
||||
/// typically tells us all the information that we need.
|
||||
fn try_pkg_config() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let host = env::var("HOST").unwrap();
|
||||
|
||||
// If we're going to windows-gnu we can use pkg-config, but only so long as
|
||||
// we're coming from a windows host.
|
||||
//
|
||||
// Otherwise if we're going to windows we probably can't use pkg-config.
|
||||
if target.contains("windows-gnu") && host.contains("windows") {
|
||||
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
|
||||
} else if target.contains("windows") {
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = match pkg_config::Config::new()
|
||||
.print_system_libs(false)
|
||||
.find("openssl")
|
||||
{
|
||||
Ok(lib) => lib,
|
||||
Err(e) => {
|
||||
println!("run pkg_config fail: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
super::validate_headers(&lib.include_paths);
|
||||
|
||||
for include in lib.include_paths.iter() {
|
||||
println!("cargo:include={}", include.display());
|
||||
}
|
||||
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
/// Attempt to find OpenSSL through vcpkg.
|
||||
///
|
||||
/// Note that if this succeeds then the function does not return as vcpkg
|
||||
/// should emit all of the cargo metadata that we need.
|
||||
#[cfg(target_env = "msvc")]
|
||||
fn try_vcpkg() {
|
||||
use vcpkg;
|
||||
|
||||
// vcpkg will not emit any metadata if it can not find libraries
|
||||
// appropriate for the target triple with the desired linkage.
|
||||
|
||||
let mut lib = vcpkg::Config::new()
|
||||
.emit_includes(true)
|
||||
.lib_name("libcrypto")
|
||||
.lib_name("libssl")
|
||||
.probe("openssl");
|
||||
|
||||
if let Err(e) = lib {
|
||||
println!(
|
||||
"note: vcpkg did not find openssl as libcrypto and libssl: {}",
|
||||
e
|
||||
);
|
||||
lib = vcpkg::Config::new()
|
||||
.emit_includes(true)
|
||||
.lib_name("libeay32")
|
||||
.lib_name("ssleay32")
|
||||
.probe("openssl");
|
||||
}
|
||||
if let Err(e) = lib {
|
||||
println!(
|
||||
"note: vcpkg did not find openssl as ssleay32 and libeay32: {}",
|
||||
e
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = lib.unwrap();
|
||||
super::validate_headers(&lib.include_paths);
|
||||
|
||||
println!("cargo:rustc-link-lib=user32");
|
||||
println!("cargo:rustc-link-lib=gdi32");
|
||||
println!("cargo:rustc-link-lib=crypt32");
|
||||
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
#[cfg(not(target_env = "msvc"))]
|
||||
fn try_vcpkg() {}
|
||||
|
||||
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
|
||||
let out = Command::new(cmd).args(args).output();
|
||||
if let Ok(ref r1) = out {
|
||||
if r1.status.success() {
|
||||
let r2 = String::from_utf8(r1.stdout.clone());
|
||||
if let Ok(r3) = r2 {
|
||||
return Some(r3.trim().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
13
openssl-sys/build/find_vendored.rs
Normal file
13
openssl-sys/build/find_vendored.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use openssl_src;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn get_openssl(_target: &str) -> (PathBuf, PathBuf) {
|
||||
let artifacts = openssl_src::Build::new().build();
|
||||
println!("cargo:vendored=1");
|
||||
println!("cargo:root={}", artifacts.lib_dir().parent().unwrap().display());
|
||||
|
||||
(
|
||||
artifacts.lib_dir().to_path_buf(),
|
||||
artifacts.include_dir().to_path_buf(),
|
||||
)
|
||||
}
|
||||
315
openssl-sys/build/main.rs
Normal file
315
openssl-sys/build/main.rs
Normal file
@ -0,0 +1,315 @@
|
||||
extern crate cc;
|
||||
#[cfg(feature = "vendored")]
|
||||
extern crate openssl_src;
|
||||
extern crate pkg_config;
|
||||
extern crate autocfg;
|
||||
#[cfg(target_env = "msvc")]
|
||||
extern crate vcpkg;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
mod cfgs;
|
||||
|
||||
#[cfg_attr(feature = "vendored", path = "find_vendored.rs")]
|
||||
#[cfg_attr(not(feature = "vendored"), path = "find_normal.rs")]
|
||||
mod find;
|
||||
|
||||
enum Version {
|
||||
Openssl11x,
|
||||
Openssl10x,
|
||||
Libressl,
|
||||
}
|
||||
|
||||
fn env_inner(name: &str) -> Option<OsString> {
|
||||
let var = env::var_os(name);
|
||||
println!("cargo:rerun-if-env-changed={}", name);
|
||||
|
||||
match var {
|
||||
Some(ref v) => println!("{} = {}", name, v.to_string_lossy()),
|
||||
None => println!("{} unset", name),
|
||||
}
|
||||
|
||||
var
|
||||
}
|
||||
|
||||
fn env(name: &str) -> Option<OsString> {
|
||||
let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_");
|
||||
let prefixed = format!("{}_{}", prefix, name);
|
||||
env_inner(&prefixed).or_else(|| env_inner(name))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
check_rustc_versions();
|
||||
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
||||
let (lib_dir, include_dir) = find::get_openssl(&target);
|
||||
|
||||
if !Path::new(&lib_dir).exists() {
|
||||
panic!(
|
||||
"OpenSSL library directory does not exist: {}",
|
||||
lib_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
if !Path::new(&include_dir).exists() {
|
||||
panic!(
|
||||
"OpenSSL include directory does not exist: {}",
|
||||
include_dir.to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
lib_dir.to_string_lossy()
|
||||
);
|
||||
println!("cargo:include={}", include_dir.to_string_lossy());
|
||||
|
||||
let version = validate_headers(&[include_dir.clone().into()]);
|
||||
|
||||
let libs_env = env("OPENSSL_LIBS");
|
||||
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
|
||||
Some(ref v) => v.split(":").collect(),
|
||||
None => match version {
|
||||
Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"],
|
||||
Version::Openssl11x if target.contains("windows") => vec!["libssl", "libcrypto"],
|
||||
_ => vec!["ssl", "crypto"],
|
||||
},
|
||||
};
|
||||
|
||||
let kind = determine_mode(Path::new(&lib_dir), &libs);
|
||||
for lib in libs.into_iter() {
|
||||
println!("cargo:rustc-link-lib={}={}", kind, lib);
|
||||
}
|
||||
|
||||
if kind == "static" && target.contains("windows") {
|
||||
println!("cargo:rustc-link-lib=dylib=gdi32");
|
||||
println!("cargo:rustc-link-lib=dylib=user32");
|
||||
println!("cargo:rustc-link-lib=dylib=crypt32");
|
||||
println!("cargo:rustc-link-lib=dylib=ws2_32");
|
||||
println!("cargo:rustc-link-lib=dylib=advapi32");
|
||||
}
|
||||
}
|
||||
|
||||
fn check_rustc_versions() {
|
||||
let cfg = autocfg::new();
|
||||
|
||||
if cfg.probe_rustc_version(1, 31) {
|
||||
println!("cargo:rustc-cfg=const_fn");
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates the header files found in `include_dir` and then returns the
|
||||
/// version string of OpenSSL.
|
||||
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
|
||||
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
|
||||
// correctly expose the right API from this crate, take a look at
|
||||
// `opensslv.h` to see what version OpenSSL claims to be.
|
||||
//
|
||||
// OpenSSL has a number of build-time configuration options which affect
|
||||
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
|
||||
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
|
||||
//
|
||||
// To handle all this conditional compilation we slurp up the configuration
|
||||
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
|
||||
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
|
||||
// account for compile differences and such.
|
||||
let mut gcc = cc::Build::new();
|
||||
for include_dir in include_dirs {
|
||||
gcc.include(include_dir);
|
||||
}
|
||||
let expanded = match gcc.file("build/expando.c").try_expand() {
|
||||
Ok(expanded) => expanded,
|
||||
Err(e) => {
|
||||
panic!(
|
||||
"
|
||||
Header expansion error:
|
||||
{:?}
|
||||
|
||||
Failed to find OpenSSL development headers.
|
||||
|
||||
You can try fixing this setting the `OPENSSL_DIR` environment variable
|
||||
pointing to your OpenSSL installation or installing OpenSSL headers package
|
||||
specific to your distribution:
|
||||
|
||||
# On Ubuntu
|
||||
sudo apt-get install libssl-dev
|
||||
# On Arch Linux
|
||||
sudo pacman -S openssl
|
||||
# On Fedora
|
||||
sudo dnf install openssl-devel
|
||||
|
||||
See rust-openssl README for more information:
|
||||
|
||||
https://github.com/sfackler/rust-openssl#linux
|
||||
",
|
||||
e
|
||||
);
|
||||
}
|
||||
};
|
||||
let expanded = String::from_utf8(expanded).unwrap();
|
||||
|
||||
let mut enabled = vec![];
|
||||
let mut openssl_version = None;
|
||||
let mut libressl_version = None;
|
||||
for line in expanded.lines() {
|
||||
let line = line.trim();
|
||||
|
||||
let openssl_prefix = "RUST_VERSION_OPENSSL_";
|
||||
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
|
||||
let conf_prefix = "RUST_CONF_";
|
||||
if line.starts_with(openssl_prefix) {
|
||||
let version = &line[openssl_prefix.len()..];
|
||||
openssl_version = Some(parse_version(version));
|
||||
} else if line.starts_with(libressl_prefix) {
|
||||
let version = &line[libressl_prefix.len()..];
|
||||
libressl_version = Some(parse_version(version));
|
||||
} else if line.starts_with(conf_prefix) {
|
||||
enabled.push(&line[conf_prefix.len()..]);
|
||||
}
|
||||
}
|
||||
|
||||
for enabled in &enabled {
|
||||
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
|
||||
}
|
||||
println!("cargo:conf={}", enabled.join(","));
|
||||
|
||||
for cfg in cfgs::get(openssl_version, libressl_version) {
|
||||
println!("cargo:rustc-cfg={}", cfg);
|
||||
}
|
||||
|
||||
if let Some(libressl_version) = libressl_version {
|
||||
println!("cargo:libressl_version_number={:x}", libressl_version);
|
||||
|
||||
let major = (libressl_version >> 28) as u8;
|
||||
let minor = (libressl_version >> 20) as u8;
|
||||
let fix = (libressl_version >> 12) as u8;
|
||||
let (major, minor, fix) = match (major, minor, fix) {
|
||||
(2, 5, 0) => ('2', '5', '0'),
|
||||
(2, 5, 1) => ('2', '5', '1'),
|
||||
(2, 5, 2) => ('2', '5', '2'),
|
||||
(2, 5, _) => ('2', '5', 'x'),
|
||||
(2, 6, 0) => ('2', '6', '0'),
|
||||
(2, 6, 1) => ('2', '6', '1'),
|
||||
(2, 6, 2) => ('2', '6', '2'),
|
||||
(2, 6, _) => ('2', '6', 'x'),
|
||||
(2, 7, _) => ('2', '7', 'x'),
|
||||
(2, 8, 0) => ('2', '8', '0'),
|
||||
(2, 8, 1) => ('2', '8', '1'),
|
||||
(2, 8, _) => ('2', '8', 'x'),
|
||||
(2, 9, 0) => ('2', '9', '0'),
|
||||
(2, 9, _) => ('2', '9', 'x'),
|
||||
(3, 0, 0) => ('3', '0', '0'),
|
||||
(3, 0, 1) => ('3', '0', '1'),
|
||||
_ => version_error(),
|
||||
};
|
||||
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version={}{}{}", major, minor, fix);
|
||||
println!("cargo:version=101");
|
||||
Version::Libressl
|
||||
} else {
|
||||
let openssl_version = openssl_version.unwrap();
|
||||
println!("cargo:version_number={:x}", openssl_version);
|
||||
|
||||
if openssl_version >= 0x1_01_02_00_0 {
|
||||
version_error()
|
||||
} else if openssl_version >= 0x1_01_01_00_0 {
|
||||
println!("cargo:version=111");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_01_00_06_0 {
|
||||
println!("cargo:version=110");
|
||||
println!("cargo:patch=f");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_01_00_00_0 {
|
||||
println!("cargo:version=110");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_00_02_00_0 {
|
||||
println!("cargo:version=102");
|
||||
Version::Openssl10x
|
||||
} else if openssl_version >= 0x1_00_01_00_0 {
|
||||
println!("cargo:version=101");
|
||||
Version::Openssl10x
|
||||
} else {
|
||||
version_error()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn version_error() -> ! {
|
||||
panic!(
|
||||
"
|
||||
|
||||
This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5
|
||||
through 3.0.1, but a different version of OpenSSL was found. The build is now aborting
|
||||
due to this version mismatch.
|
||||
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
// parses a string that looks like "0x100020cfL"
|
||||
#[allow(deprecated)] // trim_right_matches is now trim_end_matches
|
||||
fn parse_version(version: &str) -> u64 {
|
||||
// cut off the 0x prefix
|
||||
assert!(version.starts_with("0x"));
|
||||
let version = &version[2..];
|
||||
|
||||
// and the type specifier suffix
|
||||
let version = version.trim_right_matches(|c: char| match c {
|
||||
'0'..='9' | 'a'..='f' | 'A'..='F' => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
u64::from_str_radix(version, 16).unwrap()
|
||||
}
|
||||
|
||||
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
|
||||
/// of the libraries we're linking to, figure out whether we should link them
|
||||
/// statically or dynamically.
|
||||
fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
|
||||
// First see if a mode was explicitly requested
|
||||
let kind = env("OPENSSL_STATIC");
|
||||
match kind.as_ref().and_then(|s| s.to_str()).map(|s| &s[..]) {
|
||||
Some("0") => return "dylib",
|
||||
Some(_) => return "static",
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Next, see what files we actually have to link against, and see what our
|
||||
// possibilities even are.
|
||||
let files = libdir
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap())
|
||||
.map(|e| e.file_name())
|
||||
.filter_map(|e| e.into_string().ok())
|
||||
.collect::<HashSet<_>>();
|
||||
let can_static = libs
|
||||
.iter()
|
||||
.all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l)));
|
||||
let can_dylib = libs.iter().all(|l| {
|
||||
files.contains(&format!("lib{}.so", l))
|
||||
|| files.contains(&format!("{}.dll", l))
|
||||
|| files.contains(&format!("lib{}.dylib", l))
|
||||
});
|
||||
match (can_static, can_dylib) {
|
||||
(true, false) => return "static",
|
||||
(false, true) => return "dylib",
|
||||
(false, false) => {
|
||||
panic!(
|
||||
"OpenSSL libdir at `{}` does not contain the required files \
|
||||
to either statically or dynamically link OpenSSL",
|
||||
libdir.display()
|
||||
);
|
||||
}
|
||||
(true, true) => {}
|
||||
}
|
||||
|
||||
// Ok, we've got not explicit preference and can *either* link statically or
|
||||
// link dynamically. In the interest of "security upgrades" and/or "best
|
||||
// practices with security libs", let's link dynamically.
|
||||
"dylib"
|
||||
}
|
||||
44
openssl-sys/src/aes.rs
Normal file
44
openssl-sys/src/aes.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use libc::*;
|
||||
|
||||
pub const AES_ENCRYPT: c_int = 1;
|
||||
pub const AES_DECRYPT: c_int = 0;
|
||||
|
||||
pub const AES_MAXNR: c_int = 14;
|
||||
pub const AES_BLOCK_SIZE: c_int = 16;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AES_KEY {
|
||||
// There is some business with AES_LONG which is there to ensure the values here are 32 bits
|
||||
rd_key: [u32; 4 * (AES_MAXNR as usize + 1)],
|
||||
rounds: c_int,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn AES_set_encrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
|
||||
pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
|
||||
|
||||
pub fn AES_ige_encrypt(
|
||||
in_: *const c_uchar,
|
||||
out: *mut c_uchar,
|
||||
length: size_t,
|
||||
key: *const AES_KEY,
|
||||
ivec: *mut c_uchar,
|
||||
enc: c_int,
|
||||
);
|
||||
|
||||
pub fn AES_wrap_key(
|
||||
key: *mut AES_KEY,
|
||||
iv: *const c_uchar,
|
||||
out: *mut c_uchar,
|
||||
in_: *const c_uchar,
|
||||
inlen: c_uint,
|
||||
) -> c_int;
|
||||
|
||||
pub fn AES_unwrap_key(
|
||||
key: *mut AES_KEY,
|
||||
iv: *const c_uchar,
|
||||
out: *mut c_uchar,
|
||||
in_: *const c_uchar,
|
||||
inlen: c_uint,
|
||||
) -> c_int;
|
||||
}
|
||||
66
openssl-sys/src/asn1.rs
Normal file
66
openssl-sys/src/asn1.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub const V_ASN1_UTCTIME: c_int = 23;
|
||||
pub const V_ASN1_GENERALIZEDTIME: c_int = 24;
|
||||
|
||||
pub const MBSTRING_FLAG: c_int = 0x1000;
|
||||
pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG;
|
||||
pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
|
||||
pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2;
|
||||
pub const MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ASN1_ENCODING {
|
||||
pub enc: *mut c_uchar,
|
||||
pub len: c_long,
|
||||
pub modified: c_int,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
|
||||
}
|
||||
|
||||
stack!(stack_st_ASN1_OBJECT);
|
||||
|
||||
extern "C" {
|
||||
pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const c_uchar;
|
||||
#[cfg(any(all(ossl101, not(ossl110)), libressl))]
|
||||
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
|
||||
|
||||
pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
|
||||
|
||||
pub fn ASN1_STRING_free(x: *mut ASN1_STRING);
|
||||
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
|
||||
|
||||
pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME);
|
||||
pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int;
|
||||
pub fn ASN1_TIME_new() -> *mut ASN1_TIME;
|
||||
pub fn ASN1_TIME_free(tm: *mut ASN1_TIME);
|
||||
pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int;
|
||||
|
||||
pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER);
|
||||
pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long;
|
||||
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
|
||||
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
|
||||
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
|
||||
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
|
||||
#[cfg(ossl111)]
|
||||
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ASN1_STRING) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ASN1_STRING) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
151
openssl-sys/src/bio.rs
Normal file
151
openssl-sys/src/bio.rs
Normal file
@ -0,0 +1,151 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub const BIO_TYPE_NONE: c_int = 0;
|
||||
|
||||
pub const BIO_CTRL_EOF: c_int = 2;
|
||||
pub const BIO_CTRL_INFO: c_int = 3;
|
||||
pub const BIO_CTRL_FLUSH: c_int = 11;
|
||||
pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
|
||||
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_retry_read(b: *mut BIO) {
|
||||
BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY)
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_retry_write(b: *mut BIO) {
|
||||
BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY)
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_clear_retry_flags(b: *mut BIO) {
|
||||
BIO_clear_flags(b, BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY)
|
||||
}
|
||||
|
||||
pub const BIO_FLAGS_READ: c_int = 0x01;
|
||||
pub const BIO_FLAGS_WRITE: c_int = 0x02;
|
||||
pub const BIO_FLAGS_IO_SPECIAL: c_int = 0x04;
|
||||
pub const BIO_FLAGS_RWS: c_int = BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL;
|
||||
pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08;
|
||||
|
||||
pub type bio_info_cb =
|
||||
Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum BIO_METHOD {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct BIO_METHOD {
|
||||
pub type_: c_int,
|
||||
pub name: *const c_char,
|
||||
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
|
||||
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
|
||||
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
|
||||
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
|
||||
BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void)
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn BIO_s_file() -> *const BIO_METHOD;
|
||||
pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn BIO_s_file() -> *mut BIO_METHOD;
|
||||
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_STDIO"))]
|
||||
pub fn BIO_new_fp(stream: *mut FILE, close_flag: c_int) -> *mut BIO;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_set_data(a: *mut ::BIO, data: *mut c_void);
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_set_init(a: *mut ::BIO, init: c_int);
|
||||
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
|
||||
pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int;
|
||||
pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long;
|
||||
pub fn BIO_free_all(b: *mut BIO);
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn BIO_s_mem() -> *const BIO_METHOD;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn BIO_s_mem() -> *mut BIO_METHOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl102, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut BIO_METHOD;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_free(biom: *mut BIO_METHOD);
|
||||
// FIXME should wrap in Option
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_write(
|
||||
biom: *mut BIO_METHOD,
|
||||
write: unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_read(
|
||||
biom: *mut BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_puts(
|
||||
biom: *mut BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_ctrl(
|
||||
biom: *mut BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_create(
|
||||
biom: *mut BIO_METHOD,
|
||||
create: unsafe extern "C" fn(*mut BIO) -> c_int,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn BIO_meth_set_destroy(
|
||||
biom: *mut BIO_METHOD,
|
||||
destroy: unsafe extern "C" fn(*mut BIO) -> c_int,
|
||||
) -> c_int;
|
||||
}
|
||||
160
openssl-sys/src/bn.rs
Normal file
160
openssl-sys/src/bn.rs
Normal file
@ -0,0 +1,160 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type BN_ULONG = c_ulonglong;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type BN_ULONG = c_uint;
|
||||
|
||||
extern "C" {
|
||||
pub fn BN_CTX_new() -> *mut BN_CTX;
|
||||
pub fn BN_CTX_free(ctx: *mut BN_CTX);
|
||||
pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
|
||||
pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
|
||||
pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
|
||||
pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
|
||||
pub fn BN_new() -> *mut BIGNUM;
|
||||
pub fn BN_num_bits(bn: *const BIGNUM) -> c_int;
|
||||
pub fn BN_clear_free(bn: *mut BIGNUM);
|
||||
pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;
|
||||
pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
|
||||
pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
|
||||
pub fn BN_mul(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
|
||||
pub fn BN_sqr(r: *mut BIGNUM, a: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
|
||||
pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int);
|
||||
#[cfg(ossl110)]
|
||||
pub fn BN_is_negative(b: *const ::BIGNUM) -> c_int;
|
||||
|
||||
pub fn BN_div(
|
||||
dv: *mut BIGNUM,
|
||||
rem: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn BN_nnmod(
|
||||
rem: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn BN_mod_add(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn BN_mod_sub(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn BN_mod_mul(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
pub fn BN_mod_sqr(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG;
|
||||
pub fn BN_div_word(r: *mut BIGNUM, w: BN_ULONG) -> BN_ULONG;
|
||||
pub fn BN_mul_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
|
||||
pub fn BN_add_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
|
||||
pub fn BN_sub_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
|
||||
pub fn BN_set_word(bn: *mut BIGNUM, n: BN_ULONG) -> c_int;
|
||||
|
||||
pub fn BN_cmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
|
||||
pub fn BN_free(bn: *mut BIGNUM);
|
||||
pub fn BN_is_bit_set(a: *const BIGNUM, n: c_int) -> c_int;
|
||||
pub fn BN_lshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
|
||||
pub fn BN_lshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
|
||||
pub fn BN_exp(r: *mut BIGNUM, a: *const BIGNUM, p: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
|
||||
|
||||
pub fn BN_mod_exp(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
p: *const BIGNUM,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int;
|
||||
pub fn BN_rshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
|
||||
pub fn BN_rshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
|
||||
pub fn BN_bn2hex(a: *const BIGNUM) -> *mut c_char;
|
||||
pub fn BN_bn2dec(a: *const BIGNUM) -> *mut c_char;
|
||||
pub fn BN_hex2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
|
||||
pub fn BN_dec2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
|
||||
pub fn BN_gcd(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
|
||||
pub fn BN_mod_inverse(
|
||||
r: *mut BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
n: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> *mut BIGNUM;
|
||||
pub fn BN_clear(bn: *mut BIGNUM);
|
||||
pub fn BN_dup(n: *const BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_ucmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
|
||||
pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int;
|
||||
pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int;
|
||||
|
||||
pub fn BN_generate_prime_ex(
|
||||
r: *mut BIGNUM,
|
||||
bits: c_int,
|
||||
safe: c_int,
|
||||
add: *const BIGNUM,
|
||||
rem: *const BIGNUM,
|
||||
cb: *mut BN_GENCB,
|
||||
) -> c_int;
|
||||
pub fn BN_is_prime_ex(
|
||||
p: *const BIGNUM,
|
||||
checks: c_int,
|
||||
ctx: *mut BN_CTX,
|
||||
cb: *mut BN_GENCB,
|
||||
) -> c_int;
|
||||
pub fn BN_is_prime_fasttest_ex(
|
||||
p: *const BIGNUM,
|
||||
checks: c_int,
|
||||
ctx: *mut BN_CTX,
|
||||
do_trial_division: c_int,
|
||||
cb: *mut BN_GENCB,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
openssl-sys/src/cms.rs
Normal file
91
openssl-sys/src/cms.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use libc::*;
|
||||
use *;
|
||||
|
||||
pub enum CMS_ContentInfo {}
|
||||
|
||||
extern "C" {
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_ContentInfo_free(cms: *mut ::CMS_ContentInfo);
|
||||
#[cfg(ossl101)]
|
||||
pub fn i2d_CMS_ContentInfo(a: *mut ::CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn d2i_CMS_ContentInfo(a: *mut *mut ::CMS_ContentInfo, pp: *mut *const c_uchar, length: c_long) -> *mut ::CMS_ContentInfo;
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_TEXT: c_uint = 0x1;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOCERTS: c_uint = 0x2;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NO_CONTENT_VERIFY: c_uint = 0x4;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NO_ATTR_VERIFY: c_uint = 0x8;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOSIGS: c_uint = 0x4 | 0x8;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOINTERN: c_uint = 0x10;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NO_SIGNER_CERT_VERIFY: c_uint = 0x20;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOVERIFY: c_uint = 0x20;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_DETACHED: c_uint = 0x40;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_BINARY: c_uint = 0x80;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOATTR: c_uint = 0x100;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOSMIMECAP: c_uint = 0x200;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOOLDMIMETYPE: c_uint = 0x400;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_CRLFEOL: c_uint = 0x800;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_STREAM: c_uint = 0x1000;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_NOCRL: c_uint = 0x2000;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_PARTIAL: c_uint = 0x4000;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_REUSE_DIGEST: c_uint = 0x8000;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_USE_KEYID: c_uint = 0x10000;
|
||||
#[cfg(ossl101)]
|
||||
pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000;
|
||||
#[cfg(ossl102)]
|
||||
pub const CMS_KEY_PARAM: c_uint = 0x40000;
|
||||
#[cfg(ossl110)]
|
||||
pub const CMS_ASCIICRLF: c_uint = 0x80000;
|
||||
|
||||
extern "C" {
|
||||
#[cfg(ossl101)]
|
||||
pub fn SMIME_read_CMS(bio: *mut ::BIO, bcont: *mut *mut ::BIO) -> *mut ::CMS_ContentInfo;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_sign(
|
||||
signcert: *mut ::X509,
|
||||
pkey: *mut ::EVP_PKEY,
|
||||
certs: *mut ::stack_st_X509,
|
||||
data: *mut ::BIO,
|
||||
flags: c_uint,
|
||||
) -> *mut ::CMS_ContentInfo;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_encrypt(
|
||||
certs: *mut stack_st_X509,
|
||||
data: *mut ::BIO,
|
||||
cipher: *const EVP_CIPHER,
|
||||
flags: c_uint
|
||||
) -> *mut ::CMS_ContentInfo;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_decrypt(
|
||||
cms: *mut ::CMS_ContentInfo,
|
||||
pkey: *mut ::EVP_PKEY,
|
||||
cert: *mut ::X509,
|
||||
dcont: *mut ::BIO,
|
||||
out: *mut ::BIO,
|
||||
flags: c_uint,
|
||||
) -> c_int;
|
||||
}
|
||||
7
openssl-sys/src/conf.rs
Normal file
7
openssl-sys/src/conf.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use *;
|
||||
|
||||
extern "C" {
|
||||
pub fn NCONF_new(meth: *mut CONF_METHOD) -> *mut CONF;
|
||||
pub fn NCONF_default() -> *mut CONF_METHOD;
|
||||
pub fn NCONF_free(conf: *mut CONF);
|
||||
}
|
||||
130
openssl-sys/src/crypto.rs
Normal file
130
openssl-sys/src/crypto.rs
Normal file
@ -0,0 +1,130 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
#[cfg(not(ossl110))]
|
||||
pub const CRYPTO_LOCK_X509: c_int = 3;
|
||||
#[cfg(not(ossl110))]
|
||||
pub const CRYPTO_LOCK_EVP_PKEY: c_int = 10;
|
||||
#[cfg(not(ossl110))]
|
||||
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
|
||||
#[cfg(not(ossl110))]
|
||||
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
|
||||
|
||||
stack!(stack_st_void);
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
|
||||
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
|
||||
} else if #[cfg(libressl)] {
|
||||
pub const CRYPTO_EX_INDEX_SSL: c_int = 1;
|
||||
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 2;
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl271))] {
|
||||
extern "C" {
|
||||
pub fn OpenSSL_version_num() -> c_ulong;
|
||||
pub fn OpenSSL_version(key: c_int) -> *const c_char;
|
||||
}
|
||||
pub const OPENSSL_VERSION: c_int = 0;
|
||||
pub const OPENSSL_CFLAGS: c_int = 1;
|
||||
pub const OPENSSL_BUILT_ON: c_int = 2;
|
||||
pub const OPENSSL_PLATFORM: c_int = 3;
|
||||
pub const OPENSSL_DIR: c_int = 4;
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn SSLeay() -> c_ulong;
|
||||
pub fn SSLeay_version(key: c_int) -> *const c_char;
|
||||
}
|
||||
pub const SSLEAY_VERSION: c_int = 0;
|
||||
pub const SSLEAY_CFLAGS: c_int = 2;
|
||||
pub const SSLEAY_BUILT_ON: c_int = 3;
|
||||
pub const SSLEAY_PLATFORM: c_int = 4;
|
||||
pub const SSLEAY_DIR: c_int = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME should be options
|
||||
pub type CRYPTO_EX_new = unsafe extern "C" fn(
|
||||
parent: *mut c_void,
|
||||
ptr: *mut c_void,
|
||||
ad: *const CRYPTO_EX_DATA,
|
||||
idx: c_int,
|
||||
argl: c_long,
|
||||
argp: *const c_void,
|
||||
) -> c_int;
|
||||
pub type CRYPTO_EX_dup = unsafe extern "C" fn(
|
||||
to: *mut CRYPTO_EX_DATA,
|
||||
from: *mut CRYPTO_EX_DATA,
|
||||
from_d: *mut c_void,
|
||||
idx: c_int,
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
) -> c_int;
|
||||
pub type CRYPTO_EX_free = unsafe extern "C" fn(
|
||||
parent: *mut c_void,
|
||||
ptr: *mut c_void,
|
||||
ad: *mut CRYPTO_EX_DATA,
|
||||
idx: c_int,
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
);
|
||||
extern "C" {
|
||||
#[cfg(any(ossl110, libressl))]
|
||||
pub fn CRYPTO_get_ex_new_index(
|
||||
class_index: c_int,
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<CRYPTO_EX_new>,
|
||||
dup_func: Option<CRYPTO_EX_dup>,
|
||||
free_func: Option<CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
pub const CRYPTO_LOCK: c_int = 1;
|
||||
|
||||
extern "C" {
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn CRYPTO_num_locks() -> c_int;
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn CRYPTO_set_locking_callback(
|
||||
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
|
||||
);
|
||||
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
|
||||
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn CRYPTO_add_lock(
|
||||
pointer: *mut c_int,
|
||||
amount: c_int,
|
||||
type_: c_int,
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn CRYPTO_malloc(num: size_t, file: *const c_char, line: c_int) -> *mut c_void;
|
||||
pub fn CRYPTO_free(buf: *mut c_void, file: *const c_char, line: c_int);
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
|
||||
pub fn CRYPTO_free(buf: *mut c_void);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg(ossl101)]
|
||||
pub fn FIPS_mode() -> c_int;
|
||||
#[cfg(ossl101)]
|
||||
pub fn FIPS_mode_set(onoff: c_int) -> c_int;
|
||||
|
||||
pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void, len: size_t) -> c_int;
|
||||
}
|
||||
19
openssl-sys/src/dh.rs
Normal file
19
openssl-sys/src/dh.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use *;
|
||||
|
||||
extern "C" {
|
||||
pub fn DH_new() -> *mut DH;
|
||||
pub fn DH_free(dh: *mut DH);
|
||||
|
||||
pub fn d2i_DHparams(k: *mut *mut DH, pp: *mut *const c_uchar, length: c_long) -> *mut DH;
|
||||
pub fn i2d_DHparams(dh: *const DH, pp: *mut *mut c_uchar) -> c_int;
|
||||
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_1024_160() -> *mut DH;
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_2048_224() -> *mut DH;
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_2048_256() -> *mut DH;
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn DH_set0_pqg(dh: *mut DH, p: *mut BIGNUM, q: *mut BIGNUM, g: *mut BIGNUM) -> c_int;
|
||||
}
|
||||
58
openssl-sys/src/dsa.rs
Normal file
58
openssl-sys/src/dsa.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
extern "C" {
|
||||
pub fn DSA_new() -> *mut DSA;
|
||||
pub fn DSA_free(dsa: *mut DSA);
|
||||
pub fn DSA_up_ref(dsa: *mut DSA) -> c_int;
|
||||
pub fn DSA_size(dsa: *const DSA) -> c_int;
|
||||
pub fn DSA_sign(
|
||||
dummy: c_int,
|
||||
dgst: *const c_uchar,
|
||||
len: c_int,
|
||||
sigret: *mut c_uchar,
|
||||
siglen: *mut c_uint,
|
||||
dsa: *mut DSA,
|
||||
) -> c_int;
|
||||
pub fn DSA_verify(
|
||||
dummy: c_int,
|
||||
dgst: *const c_uchar,
|
||||
len: c_int,
|
||||
sigbuf: *const c_uchar,
|
||||
siglen: c_int,
|
||||
dsa: *mut DSA,
|
||||
) -> c_int;
|
||||
|
||||
pub fn d2i_DSAPublicKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
|
||||
pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long)
|
||||
-> *mut DSA;
|
||||
|
||||
pub fn DSA_generate_parameters_ex(
|
||||
dsa: *mut DSA,
|
||||
bits: c_int,
|
||||
seed: *const c_uchar,
|
||||
seed_len: c_int,
|
||||
counter_ref: *mut c_int,
|
||||
h_ret: *mut c_ulong,
|
||||
cb: *mut BN_GENCB,
|
||||
) -> c_int;
|
||||
|
||||
pub fn DSA_generate_key(dsa: *mut DSA) -> c_int;
|
||||
pub fn i2d_DSAPublicKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
|
||||
pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn DSA_get0_pqg(
|
||||
d: *const DSA,
|
||||
p: *mut *const BIGNUM,
|
||||
q: *mut *const BIGNUM,
|
||||
q: *mut *const BIGNUM,
|
||||
);
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn DSA_set0_pqg(d: *mut DSA, p: *mut BIGNUM, q: *mut BIGNUM, q: *mut BIGNUM) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM);
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn DSA_set0_key(d: *mut DSA, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int;
|
||||
}
|
||||
3
openssl-sys/src/dtls1.rs
Normal file
3
openssl-sys/src/dtls1.rs
Normal file
@ -0,0 +1,3 @@
|
||||
use libc::*;
|
||||
|
||||
pub const DTLS1_COOKIE_LENGTH: c_uint = 256;
|
||||
226
openssl-sys/src/ec.rs
Normal file
226
openssl-sys/src/ec.rs
Normal file
@ -0,0 +1,226 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum point_conversion_form_t {
|
||||
POINT_CONVERSION_COMPRESSED = 2,
|
||||
POINT_CONVERSION_UNCOMPRESSED = 4,
|
||||
POINT_CONVERSION_HYBRID = 6,
|
||||
}
|
||||
|
||||
pub enum EC_METHOD {}
|
||||
pub enum EC_GROUP {}
|
||||
pub enum EC_POINT {}
|
||||
|
||||
pub const OPENSSL_EC_NAMED_CURVE: c_int = 1;
|
||||
|
||||
extern "C" {
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
|
||||
|
||||
pub fn EC_GROUP_new(meth: *const EC_METHOD) -> *mut EC_GROUP;
|
||||
|
||||
pub fn EC_GROUP_free(group: *mut EC_GROUP);
|
||||
|
||||
pub fn EC_GROUP_get_order(
|
||||
group: *const EC_GROUP,
|
||||
order: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_GROUP_get_cofactor(
|
||||
group: *const EC_GROUP,
|
||||
cofactor: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_GROUP_get0_generator(group: *const EC_GROUP) -> *const EC_POINT;
|
||||
|
||||
pub fn EC_GROUP_get_curve_name(group: *const EC_GROUP) -> c_int;
|
||||
|
||||
pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int);
|
||||
|
||||
pub fn EC_GROUP_get_curve_GFp(
|
||||
group: *const EC_GROUP,
|
||||
p: *mut BIGNUM,
|
||||
a: *mut BIGNUM,
|
||||
b: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_GROUP_get_curve_GF2m(
|
||||
group: *const EC_GROUP,
|
||||
p: *mut BIGNUM,
|
||||
a: *mut BIGNUM,
|
||||
b: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int;
|
||||
|
||||
pub fn EC_GROUP_new_curve_GFp(
|
||||
p: *const BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> *mut EC_GROUP;
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_GROUP_new_curve_GF2m(
|
||||
p: *const BIGNUM,
|
||||
a: *const BIGNUM,
|
||||
b: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> *mut EC_GROUP;
|
||||
|
||||
pub fn EC_GROUP_new_by_curve_name(nid: c_int) -> *mut EC_GROUP;
|
||||
|
||||
pub fn EC_POINT_new(group: *const EC_GROUP) -> *mut EC_POINT;
|
||||
|
||||
pub fn EC_POINT_free(point: *mut EC_POINT);
|
||||
|
||||
pub fn EC_POINT_dup(
|
||||
p: *const EC_POINT,
|
||||
group: *const EC_GROUP,
|
||||
) -> *mut EC_POINT;
|
||||
|
||||
pub fn EC_POINT_get_affine_coordinates_GFp(
|
||||
group: *const EC_GROUP,
|
||||
p: *const EC_POINT,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
pub fn EC_POINT_get_affine_coordinates_GF2m(
|
||||
group: *const EC_GROUP,
|
||||
p: *const EC_POINT,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_POINT_point2oct(
|
||||
group: *const EC_GROUP,
|
||||
p: *const EC_POINT,
|
||||
form: point_conversion_form_t,
|
||||
buf: *mut c_uchar,
|
||||
len: size_t,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> size_t;
|
||||
|
||||
pub fn EC_POINT_oct2point(
|
||||
group: *const EC_GROUP,
|
||||
p: *mut EC_POINT,
|
||||
buf: *const c_uchar,
|
||||
len: size_t,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_POINT_add(
|
||||
group: *const EC_GROUP,
|
||||
r: *mut EC_POINT,
|
||||
a: *const EC_POINT,
|
||||
b: *const EC_POINT,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_POINT_invert(group: *const EC_GROUP, r: *mut EC_POINT, ctx: *mut BN_CTX) -> c_int;
|
||||
|
||||
pub fn EC_POINT_cmp(
|
||||
group: *const EC_GROUP,
|
||||
a: *const EC_POINT,
|
||||
b: *const EC_POINT,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_POINT_mul(
|
||||
group: *const EC_GROUP,
|
||||
r: *mut EC_POINT,
|
||||
n: *const BIGNUM,
|
||||
q: *const EC_POINT,
|
||||
m: *const BIGNUM,
|
||||
ctx: *mut BN_CTX,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EC_KEY_new() -> *mut EC_KEY;
|
||||
|
||||
pub fn EC_KEY_new_by_curve_name(nid: c_int) -> *mut EC_KEY;
|
||||
|
||||
pub fn EC_KEY_free(key: *mut EC_KEY);
|
||||
|
||||
pub fn EC_KEY_dup(key: *const EC_KEY) -> *mut EC_KEY;
|
||||
|
||||
pub fn EC_KEY_up_ref(key: *mut EC_KEY) -> c_int;
|
||||
|
||||
pub fn EC_KEY_get0_group(key: *const EC_KEY) -> *const EC_GROUP;
|
||||
|
||||
pub fn EC_KEY_set_group(key: *mut EC_KEY, group: *const EC_GROUP) -> c_int;
|
||||
|
||||
pub fn EC_KEY_get0_private_key(key: *const EC_KEY) -> *const BIGNUM;
|
||||
|
||||
pub fn EC_KEY_set_private_key(key: *mut EC_KEY, key: *const BIGNUM) -> c_int;
|
||||
|
||||
pub fn EC_KEY_get0_public_key(key: *const EC_KEY) -> *const EC_POINT;
|
||||
|
||||
pub fn EC_KEY_set_public_key(key: *mut EC_KEY, key: *const EC_POINT) -> c_int;
|
||||
|
||||
pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int;
|
||||
|
||||
pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int;
|
||||
|
||||
pub fn EC_KEY_set_public_key_affine_coordinates(
|
||||
key: *mut EC_KEY,
|
||||
x: *mut BIGNUM,
|
||||
y: *mut BIGNUM,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum ECDSA_SIG {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct ECDSA_SIG {
|
||||
pub r: *mut BIGNUM,
|
||||
pub s: *mut BIGNUM,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn ECDSA_SIG_new() -> *mut ECDSA_SIG;
|
||||
|
||||
pub fn ECDSA_SIG_free(sig: *mut ECDSA_SIG);
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn ECDSA_SIG_get0(sig: *const ECDSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM);
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn ECDSA_SIG_set0(sig: *mut ECDSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int;
|
||||
|
||||
pub fn ECDSA_do_sign(
|
||||
dgst: *const c_uchar,
|
||||
dgst_len: c_int,
|
||||
eckey: *mut EC_KEY,
|
||||
) -> *mut ECDSA_SIG;
|
||||
|
||||
pub fn ECDSA_do_verify(
|
||||
dgst: *const c_uchar,
|
||||
dgst_len: c_int,
|
||||
sig: *const ECDSA_SIG,
|
||||
eckey: *mut EC_KEY,
|
||||
) -> c_int;
|
||||
|
||||
pub fn d2i_ECDSA_SIG(
|
||||
sig: *mut *mut ECDSA_SIG,
|
||||
inp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut ECDSA_SIG;
|
||||
|
||||
pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int;
|
||||
}
|
||||
58
openssl-sys/src/err.rs
Normal file
58
openssl-sys/src/err.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use libc::*;
|
||||
|
||||
pub const ERR_TXT_MALLOCED: c_int = 0x01;
|
||||
pub const ERR_TXT_STRING: c_int = 0x02;
|
||||
|
||||
pub const ERR_LIB_PEM: c_int = 9;
|
||||
|
||||
const_fn! {
|
||||
pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong {
|
||||
((l as c_ulong & 0x0FF) << 24) |
|
||||
((f as c_ulong & 0xFFF) << 12) |
|
||||
((r as c_ulong & 0xFFF))
|
||||
}
|
||||
|
||||
pub const fn ERR_GET_LIB(l: c_ulong) -> c_int {
|
||||
((l >> 24) & 0x0FF) as c_int
|
||||
}
|
||||
|
||||
pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int {
|
||||
((l >> 12) & 0xFFF) as c_int
|
||||
}
|
||||
|
||||
pub const fn ERR_GET_REASON(l: c_ulong) -> c_int {
|
||||
(l & 0xFFF) as c_int
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ERR_STRING_DATA {
|
||||
pub error: c_ulong,
|
||||
pub string: *const c_char,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn ERR_put_error(lib: c_int, func: c_int, reason: c_int, file: *const c_char, line: c_int);
|
||||
pub fn ERR_set_error_data(data: *mut c_char, flags: c_int);
|
||||
|
||||
pub fn ERR_get_error() -> c_ulong;
|
||||
pub fn ERR_get_error_line_data(
|
||||
file: *mut *const c_char,
|
||||
line: *mut c_int,
|
||||
data: *mut *const c_char,
|
||||
flags: *mut c_int,
|
||||
) -> c_ulong;
|
||||
pub fn ERR_peek_last_error() -> c_ulong;
|
||||
pub fn ERR_clear_error();
|
||||
pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char;
|
||||
pub fn ERR_func_error_string(err: c_ulong) -> *const c_char;
|
||||
pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char;
|
||||
#[cfg(ossl110)]
|
||||
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA) -> c_int;
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA);
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn ERR_load_crypto_strings();
|
||||
|
||||
pub fn ERR_get_next_error_library() -> c_int;
|
||||
}
|
||||
405
openssl-sys/src/evp.rs
Normal file
405
openssl-sys/src/evp.rs
Normal file
@ -0,0 +1,405 @@
|
||||
use libc::*;
|
||||
use *;
|
||||
|
||||
pub const EVP_MAX_MD_SIZE: c_uint = 64;
|
||||
|
||||
pub const PKCS5_SALT_LEN: c_int = 8;
|
||||
pub const PKCS12_DEFAULT_ITER: c_int = 2048;
|
||||
|
||||
pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
|
||||
pub const EVP_PKEY_DSA: c_int = NID_dsa;
|
||||
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
|
||||
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
|
||||
#[cfg(ossl111)]
|
||||
pub const EVP_PKEY_ED25519: c_int = NID_ED25519;
|
||||
#[cfg(ossl111)]
|
||||
pub const EVP_PKEY_ED448: c_int = NID_ED448;
|
||||
pub const EVP_PKEY_HMAC: c_int = NID_hmac;
|
||||
pub const EVP_PKEY_CMAC: c_int = NID_cmac;
|
||||
|
||||
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
|
||||
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
|
||||
pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11;
|
||||
|
||||
pub unsafe fn EVP_get_digestbynid(type_: c_int) -> *const EVP_MD {
|
||||
EVP_get_digestbyname(OBJ_nid2sn(type_))
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn EVP_MD_size(md: *const EVP_MD) -> c_int;
|
||||
pub fn EVP_MD_type(md: *const EVP_MD) -> c_int;
|
||||
|
||||
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
|
||||
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
|
||||
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
|
||||
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
|
||||
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD, imple: *mut ENGINE)
|
||||
-> c_int;
|
||||
pub fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, n: size_t) -> c_int;
|
||||
pub fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
|
||||
pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD) -> c_int;
|
||||
pub fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_DigestFinalXOF(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;
|
||||
|
||||
pub fn EVP_BytesToKey(
|
||||
typ: *const EVP_CIPHER,
|
||||
md: *const EVP_MD,
|
||||
salt: *const u8,
|
||||
data: *const u8,
|
||||
datalen: c_int,
|
||||
count: c_int,
|
||||
key: *mut u8,
|
||||
iv: *mut u8,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EVP_CipherInit(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
evp: *const EVP_CIPHER,
|
||||
key: *const u8,
|
||||
iv: *const u8,
|
||||
mode: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_CipherInit_ex(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
type_: *const EVP_CIPHER,
|
||||
impl_: *mut ENGINE,
|
||||
key: *const c_uchar,
|
||||
iv: *const c_uchar,
|
||||
enc: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_CipherUpdate(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
outbuf: *mut u8,
|
||||
outlen: *mut c_int,
|
||||
inbuf: *const u8,
|
||||
inlen: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_CipherFinal(ctx: *mut EVP_CIPHER_CTX, res: *mut u8, len: *mut c_int) -> c_int;
|
||||
|
||||
pub fn EVP_DigestSignInit(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
pctx: *mut *mut EVP_PKEY_CTX,
|
||||
type_: *const EVP_MD,
|
||||
e: *mut ENGINE,
|
||||
pkey: *mut EVP_PKEY,
|
||||
) -> c_int;
|
||||
pub fn EVP_DigestSignFinal(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sig: *mut c_uchar,
|
||||
siglen: *mut size_t,
|
||||
) -> c_int;
|
||||
pub fn EVP_DigestVerifyInit(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
pctx: *mut *mut EVP_PKEY_CTX,
|
||||
type_: *const EVP_MD,
|
||||
e: *mut ENGINE,
|
||||
pkey: *mut EVP_PKEY,
|
||||
) -> c_int;
|
||||
pub fn EVP_SealInit(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
type_: *const EVP_CIPHER,
|
||||
ek: *mut *mut c_uchar,
|
||||
ekl: *mut c_int,
|
||||
iv: *mut c_uchar,
|
||||
pubk: *mut *mut EVP_PKEY,
|
||||
npubk: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_SealFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
|
||||
pub fn EVP_EncryptUpdate(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
out: *mut c_uchar,
|
||||
outl: *mut c_int,
|
||||
in_: *const u8,
|
||||
inl: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_OpenInit(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
type_: *const EVP_CIPHER,
|
||||
ek: *const c_uchar,
|
||||
ekl: c_int,
|
||||
iv: *const c_uchar,
|
||||
priv_: *mut EVP_PKEY,
|
||||
) -> c_int;
|
||||
pub fn EVP_OpenFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
|
||||
pub fn EVP_DecryptUpdate(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
out: *mut c_uchar,
|
||||
outl: *mut c_int,
|
||||
in_: *const u8,
|
||||
inl: c_int,
|
||||
) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl111b, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_size(pkey: *mut EVP_PKEY) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl111)] {
|
||||
extern "C" {
|
||||
pub fn EVP_DigestSign(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *mut c_uchar,
|
||||
siglen: *mut size_t,
|
||||
tbs: *const c_uchar,
|
||||
tbslen: size_t
|
||||
) -> c_int;
|
||||
|
||||
pub fn EVP_DigestVerify(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *const c_uchar,
|
||||
siglen: size_t,
|
||||
tbs: *const c_uchar,
|
||||
tbslen: size_t
|
||||
) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl102, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn EVP_DigestVerifyFinal(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *const c_uchar,
|
||||
siglen: size_t,
|
||||
) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn EVP_DigestVerifyFinal(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *mut c_uchar,
|
||||
siglen: size_t,
|
||||
) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
|
||||
pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
|
||||
pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int;
|
||||
pub fn EVP_CIPHER_CTX_set_key_length(ctx: *mut EVP_CIPHER_CTX, keylen: c_int) -> c_int;
|
||||
pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int;
|
||||
pub fn EVP_CIPHER_CTX_ctrl(
|
||||
ctx: *mut EVP_CIPHER_CTX,
|
||||
type_: c_int,
|
||||
arg: c_int,
|
||||
ptr: *mut c_void,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EVP_md5() -> *const EVP_MD;
|
||||
pub fn EVP_sha1() -> *const EVP_MD;
|
||||
pub fn EVP_sha224() -> *const EVP_MD;
|
||||
pub fn EVP_sha256() -> *const EVP_MD;
|
||||
pub fn EVP_sha384() -> *const EVP_MD;
|
||||
pub fn EVP_sha512() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_sha3_224() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_sha3_256() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_sha3_384() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_sha3_512() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_shake128() -> *const EVP_MD;
|
||||
#[cfg(ossl111)]
|
||||
pub fn EVP_shake256() -> *const EVP_MD;
|
||||
pub fn EVP_ripemd160() -> *const EVP_MD;
|
||||
pub fn EVP_des_ecb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_des_ede3() -> *const EVP_CIPHER;
|
||||
pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER;
|
||||
pub fn EVP_des_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_rc4() -> *const EVP_CIPHER;
|
||||
pub fn EVP_bf_ecb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_bf_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_bf_cfb64() -> *const EVP_CIPHER;
|
||||
pub fn EVP_bf_ofb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_ecb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_cfb1() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_cfb8() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_cfb128() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_ctr() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_ccm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_xts() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_cfb8() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_cfb128() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_ctr() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_cfb8() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_cfb128() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_ctr() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_ccm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_gcm() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_xts() -> *const EVP_CIPHER;
|
||||
pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER;
|
||||
#[cfg(ossl110)]
|
||||
pub fn EVP_chacha20() -> *const ::EVP_CIPHER;
|
||||
#[cfg(ossl110)]
|
||||
pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER;
|
||||
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn OPENSSL_add_all_algorithms_noconf();
|
||||
|
||||
pub fn EVP_get_digestbyname(name: *const c_char) -> *const EVP_MD;
|
||||
pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER;
|
||||
|
||||
pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *mut c_void) -> c_int;
|
||||
|
||||
pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
|
||||
pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA;
|
||||
pub fn EVP_PKEY_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA;
|
||||
pub fn EVP_PKEY_get1_DH(k: *mut EVP_PKEY) -> *mut DH;
|
||||
pub fn EVP_PKEY_get1_EC_KEY(k: *mut EVP_PKEY) -> *mut EC_KEY;
|
||||
|
||||
pub fn EVP_PKEY_new() -> *mut EVP_PKEY;
|
||||
pub fn EVP_PKEY_free(k: *mut EVP_PKEY);
|
||||
#[cfg(any(ossl110, libressl270))]
|
||||
pub fn EVP_PKEY_up_ref(pkey: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn d2i_AutoPrivateKey(
|
||||
a: *mut *mut EVP_PKEY,
|
||||
pp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn PKCS5_PBKDF2_HMAC_SHA1(
|
||||
pass: *const c_char,
|
||||
passlen: c_int,
|
||||
salt: *const u8,
|
||||
saltlen: c_int,
|
||||
iter: c_int,
|
||||
keylen: c_int,
|
||||
out: *mut u8,
|
||||
) -> c_int;
|
||||
pub fn PKCS5_PBKDF2_HMAC(
|
||||
pass: *const c_char,
|
||||
passlen: c_int,
|
||||
salt: *const c_uchar,
|
||||
saltlen: c_int,
|
||||
iter: c_int,
|
||||
digest: *const EVP_MD,
|
||||
keylen: c_int,
|
||||
out: *mut u8,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
pub fn EVP_PBE_scrypt(
|
||||
pass: *const c_char,
|
||||
passlen: size_t,
|
||||
salt: *const c_uchar,
|
||||
saltlen: size_t,
|
||||
N: u64,
|
||||
r: u64,
|
||||
p: u64,
|
||||
maxmem: u64,
|
||||
key: *mut c_uchar,
|
||||
keylen: size_t,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2;
|
||||
pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3;
|
||||
pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4;
|
||||
pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5;
|
||||
pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 6;
|
||||
pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
|
||||
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
|
||||
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
|
||||
|
||||
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
|
||||
| EVP_PKEY_OP_VERIFY
|
||||
| EVP_PKEY_OP_VERIFYRECOVER
|
||||
| EVP_PKEY_OP_SIGNCTX
|
||||
| EVP_PKEY_OP_VERIFYCTX;
|
||||
|
||||
pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
|
||||
|
||||
pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6;
|
||||
|
||||
pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
|
||||
|
||||
pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000;
|
||||
|
||||
extern "C" {
|
||||
pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
|
||||
pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
|
||||
pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX);
|
||||
|
||||
pub fn EVP_PKEY_CTX_ctrl(
|
||||
ctx: *mut EVP_PKEY_CTX,
|
||||
keytype: c_int,
|
||||
optype: c_int,
|
||||
cmd: c_int,
|
||||
p1: c_int,
|
||||
p2: *mut c_void,
|
||||
) -> c_int;
|
||||
|
||||
pub fn EVP_PKEY_new_mac_key(
|
||||
type_: c_int,
|
||||
e: *mut ENGINE,
|
||||
key: *const c_uchar,
|
||||
keylen: c_int,
|
||||
) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
|
||||
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
|
||||
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
|
||||
|
||||
pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
|
||||
pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
|
||||
}
|
||||
30
openssl-sys/src/hmac.rs
Normal file
30
openssl-sys/src/hmac.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
|
||||
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
|
||||
pub fn HMAC_CTX_cleanup(ctx: *mut HMAC_CTX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn HMAC_Init_ex(
|
||||
ctx: *mut HMAC_CTX,
|
||||
key: *const c_void,
|
||||
len: c_int,
|
||||
md: *const EVP_MD,
|
||||
impl_: *mut ENGINE,
|
||||
) -> c_int;
|
||||
pub fn HMAC_Update(ctx: *mut HMAC_CTX, data: *const c_uchar, len: size_t) -> c_int;
|
||||
pub fn HMAC_Final(ctx: *mut HMAC_CTX, md: *mut c_uchar, len: *mut c_uint) -> c_int;
|
||||
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,600 +0,0 @@
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[cfg(libressl250)]
|
||||
pub use libressl::v250::*;
|
||||
#[cfg(not(libressl250))]
|
||||
pub use libressl::v25x::*;
|
||||
|
||||
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong};
|
||||
|
||||
#[cfg(libressl250)]
|
||||
mod v250;
|
||||
#[cfg(not(libressl250))]
|
||||
mod v25x;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_ASN1_OBJECT {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509 {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_NAME {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_ATTRIBUTE {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_EXTENSION {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_GENERAL_NAME {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_void {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_SSL_CIPHER {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_OPENSSL_STRING {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _STACK {
|
||||
pub num: c_int,
|
||||
pub data: *mut *mut c_char,
|
||||
pub sorted: c_int,
|
||||
pub num_alloc: c_int,
|
||||
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIO_METHOD {
|
||||
pub type_: c_int,
|
||||
pub name: *const c_char,
|
||||
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
|
||||
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
|
||||
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
|
||||
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub meth: *const ::RSA_METHOD,
|
||||
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub n: *mut ::BIGNUM,
|
||||
pub e: *mut ::BIGNUM,
|
||||
pub d: *mut ::BIGNUM,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub dmp1: *mut ::BIGNUM,
|
||||
pub dmq1: *mut ::BIGNUM,
|
||||
pub iqmp: *mut ::BIGNUM,
|
||||
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub references: c_int,
|
||||
pub flags: c_int,
|
||||
|
||||
pub _method_mod_n: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_p: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_q: *mut ::BN_MONT_CTX,
|
||||
|
||||
pub blinding: *mut ::BN_BLINDING,
|
||||
pub mt_blinding: *mut ::BN_BLINDING,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub write_params: c_int,
|
||||
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub g: *mut ::BIGNUM,
|
||||
pub pub_key: *mut ::BIGNUM,
|
||||
pub priv_key: *mut ::BIGNUM,
|
||||
pub kinv: *mut ::BIGNUM,
|
||||
pub r: *mut ::BIGNUM,
|
||||
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut ::BN_MONT_CTX,
|
||||
pub references: c_int,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub meth: *const ::DSA_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_PKEY {
|
||||
pub type_: c_int,
|
||||
pub save_type: c_int,
|
||||
pub references: c_int,
|
||||
pub ameth: *const ::EVP_PKEY_ASN1_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub pkey: *mut c_void,
|
||||
pub save_parameters: c_int,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIO {
|
||||
pub method: *mut ::BIO_METHOD,
|
||||
pub callback: Option<
|
||||
unsafe extern "C" fn(*mut ::BIO,
|
||||
c_int,
|
||||
*const c_char,
|
||||
c_int,
|
||||
c_long,
|
||||
c_long)
|
||||
-> c_long,
|
||||
>,
|
||||
pub cb_arg: *mut c_char,
|
||||
pub init: c_int,
|
||||
pub shutdown: c_int,
|
||||
pub flags: c_int,
|
||||
pub retry_reason: c_int,
|
||||
pub num: c_int,
|
||||
pub ptr: *mut c_void,
|
||||
pub next_bio: *mut ::BIO,
|
||||
pub prev_bio: *mut ::BIO,
|
||||
pub references: c_int,
|
||||
pub num_read: c_ulong,
|
||||
pub num_write: c_ulong,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CRYPTO_EX_DATA {
|
||||
pub sk: *mut ::stack_st_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_MD_CTX {
|
||||
digest: *mut ::EVP_MD,
|
||||
engine: *mut ::ENGINE,
|
||||
flags: c_ulong,
|
||||
md_data: *mut c_void,
|
||||
pctx: *mut ::EVP_PKEY_CTX,
|
||||
update: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_CIPHER {
|
||||
pub nid: c_int,
|
||||
pub block_size: c_int,
|
||||
pub key_len: c_int,
|
||||
pub iv_len: c_int,
|
||||
pub flags: c_ulong,
|
||||
pub init: Option<
|
||||
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
|
||||
*const c_uchar,
|
||||
*const c_uchar,
|
||||
c_int)
|
||||
-> c_int,
|
||||
>,
|
||||
pub do_cipher: Option<
|
||||
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
|
||||
*mut c_uchar,
|
||||
*const c_uchar,
|
||||
size_t)
|
||||
-> c_int,
|
||||
>,
|
||||
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
|
||||
pub ctx_size: c_int,
|
||||
pub set_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
|
||||
pub get_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
|
||||
pub ctrl:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
|
||||
pub app_data: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct HMAC_CTX {
|
||||
md: *mut ::EVP_MD,
|
||||
md_ctx: ::EVP_MD_CTX,
|
||||
i_ctx: ::EVP_MD_CTX,
|
||||
o_ctx: ::EVP_MD_CTX,
|
||||
key_length: c_uint,
|
||||
key: [c_uchar; 128],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIGNUM {
|
||||
pub d: *mut ::BN_ULONG,
|
||||
pub top: c_int,
|
||||
pub dmax: c_int,
|
||||
pub neg: c_int,
|
||||
pub flags: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DH {
|
||||
pub pad: c_int,
|
||||
pub version: c_int,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub g: *mut ::BIGNUM,
|
||||
pub length: c_long,
|
||||
pub pub_key: *mut ::BIGNUM,
|
||||
pub priv_key: *mut ::BIGNUM,
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut ::BN_MONT_CTX,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub j: *mut ::BIGNUM,
|
||||
pub seed: *mut c_uchar,
|
||||
pub seedlen: c_int,
|
||||
pub counter: *mut ::BIGNUM,
|
||||
pub references: c_int,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub meth: *const ::DH_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509 {
|
||||
pub cert_info: *mut X509_CINF,
|
||||
pub sig_alg: *mut ::X509_ALGOR,
|
||||
pub signature: *mut ::ASN1_BIT_STRING,
|
||||
pub valid: c_int,
|
||||
pub references: c_int,
|
||||
pub name: *mut c_char,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub ex_pathlen: c_long,
|
||||
pub ex_pcpathlen: c_long,
|
||||
pub ex_flags: c_ulong,
|
||||
pub ex_kusage: c_ulong,
|
||||
pub ex_xkusage: c_ulong,
|
||||
pub ex_nscert: c_ulong,
|
||||
skid: *mut c_void,
|
||||
akid: *mut c_void,
|
||||
policy_cache: *mut c_void,
|
||||
crldp: *mut c_void,
|
||||
altname: *mut c_void,
|
||||
nc: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
|
||||
sha1_hash: [c_uchar; 20],
|
||||
aux: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_CINF {
|
||||
version: *mut c_void,
|
||||
serialNumber: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
issuer: *mut c_void,
|
||||
pub validity: *mut X509_VAL,
|
||||
subject: *mut c_void,
|
||||
key: *mut c_void,
|
||||
issuerUID: *mut c_void,
|
||||
subjectUID: *mut c_void,
|
||||
pub extensions: *mut stack_st_X509_EXTENSION,
|
||||
enc: ASN1_ENCODING,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_ALGOR {
|
||||
pub algorithm: *mut ::ASN1_OBJECT,
|
||||
parameter: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ASN1_ENCODING {
|
||||
pub enc: *mut c_uchar,
|
||||
pub len: c_long,
|
||||
pub modified: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VAL {
|
||||
pub notBefore: *mut ::ASN1_TIME,
|
||||
pub notAfter: *mut ::ASN1_TIME,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ_INFO {
|
||||
pub enc: ASN1_ENCODING,
|
||||
pub version: *mut ::ASN1_INTEGER,
|
||||
pub subject: *mut ::X509_NAME,
|
||||
pubkey: *mut c_void,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ {
|
||||
pub req_info: *mut X509_REQ_INFO,
|
||||
sig_alg: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
references: c_int,
|
||||
}
|
||||
|
||||
pub enum X509_VERIFY_PARAM_ID {}
|
||||
pub enum PKCS12 {}
|
||||
|
||||
pub const SSL_CTRL_GET_SESSION_REUSED: c_int = 8;
|
||||
pub const SSL_CTRL_OPTIONS: c_int = 32;
|
||||
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
||||
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
|
||||
|
||||
#[cfg(any(libressl261, libressl262, libressl26x))]
|
||||
pub const SSL_OP_ALL: c_ulong = 0x4;
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x)))]
|
||||
pub const SSL_OP_ALL: c_ulong = 0x80000014;
|
||||
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
|
||||
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0;
|
||||
pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: c_ulong = 0x0;
|
||||
pub const SSL_OP_NO_SSLv3: c_ulong = 0x0;
|
||||
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x0;
|
||||
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0;
|
||||
#[cfg(any(libressl261, libressl262, libressl26x))]
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0;
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x)))]
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
|
||||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;
|
||||
|
||||
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
|
||||
|
||||
pub const SSLEAY_VERSION: c_int = 0;
|
||||
pub const SSLEAY_CFLAGS: c_int = 2;
|
||||
pub const SSLEAY_BUILT_ON: c_int = 3;
|
||||
pub const SSLEAY_PLATFORM: c_int = 4;
|
||||
pub const SSLEAY_DIR: c_int = 5;
|
||||
|
||||
pub const CRYPTO_LOCK_X509: c_int = 3;
|
||||
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
|
||||
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
|
||||
|
||||
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
|
||||
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
|
||||
*mut Vec<Option<MutexGuard<'static, ()>>>;
|
||||
|
||||
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
|
||||
let mutex = &(*MUTEXES)[n as usize];
|
||||
|
||||
if mode & ::CRYPTO_LOCK != 0 {
|
||||
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
|
||||
} else {
|
||||
&(*GUARDS)[n as usize].take().expect("lock already unlocked");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
static INIT: Once = ONCE_INIT;
|
||||
|
||||
INIT.call_once(|| unsafe {
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
OPENSSL_add_all_algorithms_noconf();
|
||||
|
||||
let num_locks = ::CRYPTO_num_locks();
|
||||
let mut mutexes = Box::new(Vec::new());
|
||||
for _ in 0..num_locks {
|
||||
mutexes.push(Mutex::new(()));
|
||||
}
|
||||
MUTEXES = mem::transmute(mutexes);
|
||||
let guards: Box<Vec<Option<MutexGuard<()>>>> =
|
||||
Box::new((0..num_locks).map(|_| None).collect());
|
||||
GUARDS = mem::transmute(guards);
|
||||
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
set_id_callback();
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn set_id_callback() {
|
||||
unsafe extern "C" fn thread_id() -> c_ulong {
|
||||
::libc::pthread_self() as c_ulong
|
||||
}
|
||||
|
||||
unsafe {
|
||||
CRYPTO_set_id_callback(thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn set_id_callback() {}
|
||||
|
||||
// macros
|
||||
|
||||
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx,
|
||||
SSL_CTRL_SET_ECDH_AUTO,
|
||||
onoff as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_int
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
|
||||
::SSL_ctrl(
|
||||
ssl,
|
||||
SSL_CTRL_SET_ECDH_AUTO,
|
||||
onoff as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_int
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
|
||||
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
|
||||
pub fn BIO_s_file() -> *mut BIO_METHOD;
|
||||
pub fn BIO_s_mem() -> *mut BIO_METHOD;
|
||||
|
||||
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
|
||||
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
|
||||
pub fn CRYPTO_free(buf: *mut c_void);
|
||||
pub fn CRYPTO_num_locks() -> c_int;
|
||||
pub fn CRYPTO_set_locking_callback(
|
||||
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
|
||||
);
|
||||
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
|
||||
|
||||
pub fn ERR_load_crypto_strings();
|
||||
|
||||
pub fn RSA_generate_key(
|
||||
modsz: c_int,
|
||||
e: c_ulong,
|
||||
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
|
||||
cbarg: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
|
||||
pub fn OCSP_cert_to_id(
|
||||
dgst: *const ::EVP_MD,
|
||||
subject: *mut ::X509,
|
||||
issuer: *mut ::X509,
|
||||
) -> *mut ::OCSP_CERTID;
|
||||
|
||||
pub fn PKCS12_create(
|
||||
pass: *mut c_char,
|
||||
friendly_name: *mut c_char,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
ca: *mut stack_st_X509,
|
||||
nid_key: c_int,
|
||||
nid_cert: c_int,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
keytype: c_int,
|
||||
) -> *mut PKCS12;
|
||||
|
||||
pub fn SSL_library_init() -> c_int;
|
||||
pub fn SSL_load_error_strings();
|
||||
pub fn OPENSSL_add_all_algorithms_noconf();
|
||||
pub fn HMAC_CTX_init(ctx: *mut ::HMAC_CTX);
|
||||
pub fn HMAC_CTX_cleanup(ctx: *mut ::HMAC_CTX);
|
||||
pub fn TLSv1_method() -> *const ::SSL_METHOD;
|
||||
pub fn SSLv23_method() -> *const ::SSL_METHOD;
|
||||
pub fn TLSv1_1_method() -> *const ::SSL_METHOD;
|
||||
pub fn TLSv1_2_method() -> *const ::SSL_METHOD;
|
||||
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
|
||||
pub fn SSL_get_ex_new_index(
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<::CRYPTO_EX_new>,
|
||||
dup_func: Option<::CRYPTO_EX_dup>,
|
||||
free_func: Option<::CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
pub fn SSL_set_tmp_ecdh_callback(
|
||||
ssl: *mut ::SSL,
|
||||
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
|
||||
-> *mut ::EC_KEY,
|
||||
);
|
||||
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
|
||||
pub fn SSL_CTX_get_ex_new_index(
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<::CRYPTO_EX_new>,
|
||||
dup_func: Option<::CRYPTO_EX_dup>,
|
||||
free_func: Option<::CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
pub fn SSL_CTX_set_tmp_ecdh_callback(
|
||||
ctx: *mut ::SSL_CTX,
|
||||
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
|
||||
-> *mut ::EC_KEY,
|
||||
);
|
||||
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_get_ext_d2i(
|
||||
x: *mut ::X509,
|
||||
nid: c_int,
|
||||
crit: *mut c_int,
|
||||
idx: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
pub fn X509_NAME_add_entry_by_NID(
|
||||
x: *mut ::X509_NAME,
|
||||
field: c_int,
|
||||
ty: c_int,
|
||||
bytes: *mut c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
|
||||
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
|
||||
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
pub fn X509V3_EXT_nconf_nid(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
ext_nid: c_int,
|
||||
value: *mut c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn X509V3_EXT_nconf(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
name: *mut c_char,
|
||||
value: *mut c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
|
||||
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
|
||||
pub fn CRYPTO_add_lock(
|
||||
pointer: *mut c_int,
|
||||
amount: c_int,
|
||||
type_: c_int,
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
|
||||
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
|
||||
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn sk_new_null() -> *mut _STACK;
|
||||
pub fn sk_num(st: *const _STACK) -> c_int;
|
||||
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
|
||||
pub fn sk_free(st: *mut _STACK);
|
||||
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
|
||||
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
|
||||
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
|
||||
|
||||
pub fn SSLeay() -> c_ulong;
|
||||
pub fn SSLeay_version(key: c_int) -> *const c_char;
|
||||
}
|
||||
@ -1,221 +0,0 @@
|
||||
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
type_: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut c_void,
|
||||
wbio: *mut c_void,
|
||||
bbio: *mut c_void,
|
||||
rwstate: c_int,
|
||||
in_handshake: c_int,
|
||||
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
|
||||
pub server: c_int,
|
||||
new_session: c_int,
|
||||
quiet_shutdown: c_int,
|
||||
shutdown: c_int,
|
||||
state: c_int,
|
||||
rstate: c_int,
|
||||
init_buf: *mut c_void,
|
||||
init_msg: *mut c_void,
|
||||
init_num: c_int,
|
||||
init_off: c_int,
|
||||
packet: *mut c_uchar,
|
||||
packet_length: c_uint,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: Option<
|
||||
unsafe extern "C" fn(c_int,
|
||||
c_int,
|
||||
c_int,
|
||||
*const c_void,
|
||||
size_t,
|
||||
*mut SSL,
|
||||
*mut c_void),
|
||||
>,
|
||||
msg_callback_arg: *mut c_void,
|
||||
hit: c_int,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
|
||||
mac_flags: c_int,
|
||||
aead_read_ctx: *mut c_void,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut ::EVP_MD_CTX,
|
||||
aead_write_ctx: *mut c_void,
|
||||
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
write_hash: *mut ::EVP_MD_CTX,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
generate_session_id: ::GEN_SESSION_CB,
|
||||
verify_mode: c_int,
|
||||
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
|
||||
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
debug: c_int,
|
||||
verify_result: c_long,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
client_CA: *mut stack_st_X509_NAME,
|
||||
references: c_int,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
first_packet: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
tlsext_debug_cb:
|
||||
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
|
||||
tlsext_debug_arg: *mut c_void,
|
||||
tlsext_hostname: *mut c_char,
|
||||
servername_done: c_int,
|
||||
tlsext_status_type: c_int,
|
||||
tlsext_status_expected: c_int,
|
||||
tlsext_ocsp_ids: *mut c_void,
|
||||
tlsext_ocsp_exts: *mut c_void,
|
||||
tlsext_ocsp_resp: *mut c_uchar,
|
||||
tlsext_ocsp_resplen: c_int,
|
||||
tlsext_ticket_expected: c_int,
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
tlsext_session_ticket: *mut c_void,
|
||||
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
|
||||
tls_session_ticket_ext_cb_arg: *mut c_void,
|
||||
tls_session_secret_cb: ::tls_session_secret_cb_fn,
|
||||
tls_session_secret_cb_arg: *mut c_void,
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
next_proto_negotiated: *mut c_uchar,
|
||||
next_proto_negotiated_len: c_uchar,
|
||||
srtp_profiles: *mut c_void,
|
||||
srtp_profile: *mut c_void,
|
||||
tlsext_heartbeat: c_uint,
|
||||
tlsext_hb_pending: c_uint,
|
||||
tlsext_hb_seq: c_uint,
|
||||
alpn_client_proto_list: *mut c_uchar,
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
renegotiate: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *mut c_void,
|
||||
cipher_list: *mut c_void,
|
||||
cipher_list_by_id: *mut c_void,
|
||||
cert_store: *mut c_void,
|
||||
sessions: *mut c_void,
|
||||
session_cache_size: c_ulong,
|
||||
session_cache_head: *mut c_void,
|
||||
session_cache_tail: *mut c_void,
|
||||
session_cache_mode: c_int,
|
||||
session_timeout: c_long,
|
||||
new_session_cb: *mut c_void,
|
||||
remove_session_cb: *mut c_void,
|
||||
get_session_cb: *mut c_void,
|
||||
stats: [c_int; 11],
|
||||
pub references: c_int,
|
||||
app_verify_callback: *mut c_void,
|
||||
app_verify_arg: *mut c_void,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
client_cert_cb: *mut c_void,
|
||||
app_gen_cookie_cb: *mut c_void,
|
||||
app_verify_cookie_cb: *mut c_void,
|
||||
ex_dat: ::CRYPTO_EX_DATA,
|
||||
rsa_md5: *mut c_void,
|
||||
md5: *mut c_void,
|
||||
sha1: *mut c_void,
|
||||
extra_certs: *mut c_void,
|
||||
comp_methods: *mut c_void,
|
||||
info_callback: *mut c_void,
|
||||
client_CA: *mut c_void,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
cert: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: *mut c_void,
|
||||
msg_callback_arg: *mut c_void,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; 32],
|
||||
default_verify_callback: *mut c_void,
|
||||
generate_session_id: *mut c_void,
|
||||
param: *mut c_void,
|
||||
quiet_shutdown: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
|
||||
client_cert_engine: *mut c_void,
|
||||
|
||||
tlsext_servername_callback: *mut c_void,
|
||||
tlsect_servername_arg: *mut c_void,
|
||||
tlsext_tick_key_name: [c_uchar; 16],
|
||||
tlsext_tick_hmac_key: [c_uchar; 16],
|
||||
tlsext_tick_aes_key: [c_uchar; 16],
|
||||
tlsext_ticket_key_cb: *mut c_void,
|
||||
tlsext_status_cb: *mut c_void,
|
||||
tlsext_status_arg: *mut c_void,
|
||||
tlsext_opaque_prf_input_callback: *mut c_void,
|
||||
tlsext_opaque_prf_input_callback_arg: *mut c_void,
|
||||
|
||||
next_protos_advertised_cb: *mut c_void,
|
||||
next_protos_advertised_cb_arg: *mut c_void,
|
||||
next_proto_select_cb: *mut c_void,
|
||||
next_proto_select_cb_arg: *mut c_void,
|
||||
|
||||
srtp_profiles: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_SESSION {
|
||||
ssl_version: c_int,
|
||||
pub master_key_length: c_int,
|
||||
pub master_key: [c_uchar; 48],
|
||||
session_id_length: c_uint,
|
||||
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
not_resumable: c_int,
|
||||
sess_cert: *mut c_void,
|
||||
peer: *mut X509,
|
||||
verify_result: c_long,
|
||||
timeout: c_long,
|
||||
time: time_t,
|
||||
pub references: c_int,
|
||||
cipher: *const c_void,
|
||||
cipher_id: c_ulong,
|
||||
ciphers: *mut c_void,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
prev: *mut c_void,
|
||||
next: *mut c_void,
|
||||
tlsext_hostname: *mut c_char,
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
tlsext_ecpointformatlist: *mut u8,
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
tlsext_ellipticcurvelist: *mut u16,
|
||||
tlsext_tick: *mut c_uchar,
|
||||
tlsext_ticklen: size_t,
|
||||
tlsext_tick_lifetime_hint: c_long,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
//pub id: *mut X509_VERIFY_PARAM_ID,
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut ::BIO,
|
||||
wbio: *mut ::BIO,
|
||||
bbio: *mut ::BIO,
|
||||
pub server: c_int,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
verify_mode: c_int,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
verify_result: c_long,
|
||||
references: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
tlsext_hostname: *mut c_char,
|
||||
tlsext_status_type: c_int,
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut EVP_MD_CTX,
|
||||
internal: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *const ::SSL_METHOD,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cert_store: *mut c_void,
|
||||
session_timeout: c_long,
|
||||
pub references: c_int,
|
||||
extra_certs: *mut stack_st_X509,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
param: *mut ::X509_VERIFY_PARAM,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
internal: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_SESSION {
|
||||
ssl_version: c_int,
|
||||
pub master_key_length: c_int,
|
||||
pub master_key: [c_uchar; 48],
|
||||
session_id_length: c_uint,
|
||||
session_id: [c_uchar; ::SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
peer: *mut ::X509,
|
||||
verify_result: c_long,
|
||||
timeout: c_long,
|
||||
time: time_t,
|
||||
pub references: c_int,
|
||||
cipher: *const ::SSL_CIPHER,
|
||||
cipher_id: c_long,
|
||||
ciphers: *mut stack_st_SSL_CIPHER,
|
||||
tlsext_hostname: *mut c_char,
|
||||
tlsext_tick: *mut c_uchar,
|
||||
tlsext_ticklen: size_t,
|
||||
tlsext_tick_lifetime_int: c_long,
|
||||
internal: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
policies: *mut stack_st_ASN1_OBJECT,
|
||||
id: *mut c_void,
|
||||
}
|
||||
87
openssl-sys/src/macros.rs
Normal file
87
openssl-sys/src/macros.rs
Normal file
@ -0,0 +1,87 @@
|
||||
// vendored from the cfg-if crate to avoid breaking ctest
|
||||
macro_rules! cfg_if {
|
||||
// match if/else chains with a final `else`
|
||||
($(
|
||||
if #[cfg($($meta:meta),*)] { $($it:item)* }
|
||||
) else * else {
|
||||
$($it2:item)*
|
||||
}) => {
|
||||
cfg_if! {
|
||||
@__items
|
||||
() ;
|
||||
$( ( ($($meta),*) ($($it)*) ), )*
|
||||
( () ($($it2)*) ),
|
||||
}
|
||||
};
|
||||
|
||||
// match if/else chains lacking a final `else`
|
||||
(
|
||||
if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
|
||||
$(
|
||||
else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
|
||||
)*
|
||||
) => {
|
||||
cfg_if! {
|
||||
@__items
|
||||
() ;
|
||||
( ($($i_met),*) ($($i_it)*) ),
|
||||
$( ( ($($e_met),*) ($($e_it)*) ), )*
|
||||
( () () ),
|
||||
}
|
||||
};
|
||||
|
||||
// Internal and recursive macro to emit all the items
|
||||
//
|
||||
// Collects all the negated cfgs in a list at the beginning and after the
|
||||
// semicolon is all the remaining items
|
||||
(@__items ($($not:meta,)*) ; ) => {};
|
||||
(@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
|
||||
// Emit all items within one block, applying an approprate #[cfg]. The
|
||||
// #[cfg] will require all `$m` matchers specified and must also negate
|
||||
// all previous matchers.
|
||||
cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
|
||||
|
||||
// Recurse to emit all other items in `$rest`, and when we do so add all
|
||||
// our `$m` matchers to the list of `$not` matchers as future emissions
|
||||
// will have to negate everything we just matched as well.
|
||||
cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
|
||||
};
|
||||
|
||||
// Internal macro to Apply a cfg attribute to a list of items
|
||||
(@__apply $m:meta, $($it:item)*) => {
|
||||
$(#[$m] $it)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! stack {
|
||||
($t:ident) => {
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum $t {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct $t {
|
||||
pub stack: ::_STACK,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(const_fn)]
|
||||
macro_rules! const_fn {
|
||||
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
|
||||
$(
|
||||
pub const fn $name($($arg: $t),*) -> $ret $b
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(const_fn))]
|
||||
macro_rules! const_fn {
|
||||
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
|
||||
$(
|
||||
pub fn $name($($arg: $t),*) -> $ret $b
|
||||
)*
|
||||
}
|
||||
}
|
||||
918
openssl-sys/src/obj_mac.rs
Normal file
918
openssl-sys/src/obj_mac.rs
Normal file
@ -0,0 +1,918 @@
|
||||
use libc::*;
|
||||
|
||||
pub const NID_undef: c_int = 0;
|
||||
pub const NID_itu_t: c_int = 645;
|
||||
pub const NID_ccitt: c_int = 404;
|
||||
pub const NID_iso: c_int = 181;
|
||||
pub const NID_joint_iso_itu_t: c_int = 646;
|
||||
pub const NID_joint_iso_ccitt: c_int = 393;
|
||||
pub const NID_member_body: c_int = 182;
|
||||
pub const NID_identified_organization: c_int = 676;
|
||||
pub const NID_hmac_md5: c_int = 780;
|
||||
pub const NID_hmac_sha1: c_int = 781;
|
||||
pub const NID_certicom_arc: c_int = 677;
|
||||
pub const NID_international_organizations: c_int = 647;
|
||||
pub const NID_wap: c_int = 678;
|
||||
pub const NID_wap_wsg: c_int = 679;
|
||||
pub const NID_selected_attribute_types: c_int = 394;
|
||||
pub const NID_clearance: c_int = 395;
|
||||
pub const NID_ISO_US: c_int = 183;
|
||||
pub const NID_X9_57: c_int = 184;
|
||||
pub const NID_X9cm: c_int = 185;
|
||||
pub const NID_dsa: c_int = 116;
|
||||
pub const NID_dsaWithSHA1: c_int = 113;
|
||||
pub const NID_ansi_X9_62: c_int = 405;
|
||||
pub const NID_X9_62_prime_field: c_int = 406;
|
||||
pub const NID_X9_62_characteristic_two_field: c_int = 407;
|
||||
pub const NID_X9_62_id_characteristic_two_basis: c_int = 680;
|
||||
pub const NID_X9_62_onBasis: c_int = 681;
|
||||
pub const NID_X9_62_tpBasis: c_int = 682;
|
||||
pub const NID_X9_62_ppBasis: c_int = 683;
|
||||
pub const NID_X9_62_id_ecPublicKey: c_int = 408;
|
||||
pub const NID_X9_62_c2pnb163v1: c_int = 684;
|
||||
pub const NID_X9_62_c2pnb163v2: c_int = 685;
|
||||
pub const NID_X9_62_c2pnb163v3: c_int = 686;
|
||||
pub const NID_X9_62_c2pnb176v1: c_int = 687;
|
||||
pub const NID_X9_62_c2tnb191v1: c_int = 688;
|
||||
pub const NID_X9_62_c2tnb191v2: c_int = 689;
|
||||
pub const NID_X9_62_c2tnb191v3: c_int = 690;
|
||||
pub const NID_X9_62_c2onb191v4: c_int = 691;
|
||||
pub const NID_X9_62_c2onb191v5: c_int = 692;
|
||||
pub const NID_X9_62_c2pnb208w1: c_int = 693;
|
||||
pub const NID_X9_62_c2tnb239v1: c_int = 694;
|
||||
pub const NID_X9_62_c2tnb239v2: c_int = 695;
|
||||
pub const NID_X9_62_c2tnb239v3: c_int = 696;
|
||||
pub const NID_X9_62_c2onb239v4: c_int = 697;
|
||||
pub const NID_X9_62_c2onb239v5: c_int = 698;
|
||||
pub const NID_X9_62_c2pnb272w1: c_int = 699;
|
||||
pub const NID_X9_62_c2pnb304w1: c_int = 700;
|
||||
pub const NID_X9_62_c2tnb359v1: c_int = 701;
|
||||
pub const NID_X9_62_c2pnb368w1: c_int = 702;
|
||||
pub const NID_X9_62_c2tnb431r1: c_int = 703;
|
||||
pub const NID_X9_62_prime192v1: c_int = 409;
|
||||
pub const NID_X9_62_prime192v2: c_int = 410;
|
||||
pub const NID_X9_62_prime192v3: c_int = 411;
|
||||
pub const NID_X9_62_prime239v1: c_int = 412;
|
||||
pub const NID_X9_62_prime239v2: c_int = 413;
|
||||
pub const NID_X9_62_prime239v3: c_int = 414;
|
||||
pub const NID_X9_62_prime256v1: c_int = 415;
|
||||
pub const NID_ecdsa_with_SHA1: c_int = 416;
|
||||
pub const NID_ecdsa_with_Recommended: c_int = 791;
|
||||
pub const NID_ecdsa_with_Specified: c_int = 792;
|
||||
pub const NID_ecdsa_with_SHA224: c_int = 793;
|
||||
pub const NID_ecdsa_with_SHA256: c_int = 794;
|
||||
pub const NID_ecdsa_with_SHA384: c_int = 795;
|
||||
pub const NID_ecdsa_with_SHA512: c_int = 796;
|
||||
pub const NID_secp112r1: c_int = 704;
|
||||
pub const NID_secp112r2: c_int = 705;
|
||||
pub const NID_secp128r1: c_int = 706;
|
||||
pub const NID_secp128r2: c_int = 707;
|
||||
pub const NID_secp160k1: c_int = 708;
|
||||
pub const NID_secp160r1: c_int = 709;
|
||||
pub const NID_secp160r2: c_int = 710;
|
||||
pub const NID_secp192k1: c_int = 711;
|
||||
pub const NID_secp224k1: c_int = 712;
|
||||
pub const NID_secp224r1: c_int = 713;
|
||||
pub const NID_secp256k1: c_int = 714;
|
||||
pub const NID_secp384r1: c_int = 715;
|
||||
pub const NID_secp521r1: c_int = 716;
|
||||
pub const NID_sect113r1: c_int = 717;
|
||||
pub const NID_sect113r2: c_int = 718;
|
||||
pub const NID_sect131r1: c_int = 719;
|
||||
pub const NID_sect131r2: c_int = 720;
|
||||
pub const NID_sect163k1: c_int = 721;
|
||||
pub const NID_sect163r1: c_int = 722;
|
||||
pub const NID_sect163r2: c_int = 723;
|
||||
pub const NID_sect193r1: c_int = 724;
|
||||
pub const NID_sect193r2: c_int = 725;
|
||||
pub const NID_sect233k1: c_int = 726;
|
||||
pub const NID_sect233r1: c_int = 727;
|
||||
pub const NID_sect239k1: c_int = 728;
|
||||
pub const NID_sect283k1: c_int = 729;
|
||||
pub const NID_sect283r1: c_int = 730;
|
||||
pub const NID_sect409k1: c_int = 731;
|
||||
pub const NID_sect409r1: c_int = 732;
|
||||
pub const NID_sect571k1: c_int = 733;
|
||||
pub const NID_sect571r1: c_int = 734;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls1: c_int = 735;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls3: c_int = 736;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls4: c_int = 737;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls5: c_int = 738;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls6: c_int = 739;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls7: c_int = 740;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls8: c_int = 741;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls9: c_int = 742;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls10: c_int = 743;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls11: c_int = 744;
|
||||
pub const NID_wap_wsg_idm_ecid_wtls12: c_int = 745;
|
||||
pub const NID_cast5_cbc: c_int = 108;
|
||||
pub const NID_cast5_ecb: c_int = 109;
|
||||
pub const NID_cast5_cfb64: c_int = 110;
|
||||
pub const NID_cast5_ofb64: c_int = 111;
|
||||
pub const NID_pbeWithMD5AndCast5_CBC: c_int = 112;
|
||||
pub const NID_id_PasswordBasedMAC: c_int = 782;
|
||||
pub const NID_id_DHBasedMac: c_int = 783;
|
||||
pub const NID_rsadsi: c_int = 1;
|
||||
pub const NID_pkcs: c_int = 2;
|
||||
pub const NID_pkcs1: c_int = 186;
|
||||
pub const NID_rsaEncryption: c_int = 6;
|
||||
pub const NID_md2WithRSAEncryption: c_int = 7;
|
||||
pub const NID_md4WithRSAEncryption: c_int = 396;
|
||||
pub const NID_md5WithRSAEncryption: c_int = 8;
|
||||
pub const NID_sha1WithRSAEncryption: c_int = 65;
|
||||
pub const NID_rsaesOaep: c_int = 919;
|
||||
pub const NID_mgf1: c_int = 911;
|
||||
pub const NID_rsassaPss: c_int = 912;
|
||||
pub const NID_sha256WithRSAEncryption: c_int = 668;
|
||||
pub const NID_sha384WithRSAEncryption: c_int = 669;
|
||||
pub const NID_sha512WithRSAEncryption: c_int = 670;
|
||||
pub const NID_sha224WithRSAEncryption: c_int = 671;
|
||||
pub const NID_pkcs3: c_int = 27;
|
||||
pub const NID_dhKeyAgreement: c_int = 28;
|
||||
pub const NID_pkcs5: c_int = 187;
|
||||
pub const NID_pbeWithMD2AndDES_CBC: c_int = 9;
|
||||
pub const NID_pbeWithMD5AndDES_CBC: c_int = 10;
|
||||
pub const NID_pbeWithMD2AndRC2_CBC: c_int = 168;
|
||||
pub const NID_pbeWithMD5AndRC2_CBC: c_int = 169;
|
||||
pub const NID_pbeWithSHA1AndDES_CBC: c_int = 170;
|
||||
pub const NID_pbeWithSHA1AndRC2_CBC: c_int = 68;
|
||||
pub const NID_id_pbkdf2: c_int = 69;
|
||||
pub const NID_pbes2: c_int = 161;
|
||||
pub const NID_pbmac1: c_int = 162;
|
||||
pub const NID_pkcs7: c_int = 20;
|
||||
pub const NID_pkcs7_data: c_int = 21;
|
||||
pub const NID_pkcs7_signed: c_int = 22;
|
||||
pub const NID_pkcs7_enveloped: c_int = 23;
|
||||
pub const NID_pkcs7_signedAndEnveloped: c_int = 24;
|
||||
pub const NID_pkcs7_digest: c_int = 25;
|
||||
pub const NID_pkcs7_encrypted: c_int = 26;
|
||||
pub const NID_pkcs9: c_int = 47;
|
||||
pub const NID_pkcs9_emailAddress: c_int = 48;
|
||||
pub const NID_pkcs9_unstructuredName: c_int = 49;
|
||||
pub const NID_pkcs9_contentType: c_int = 50;
|
||||
pub const NID_pkcs9_messageDigest: c_int = 51;
|
||||
pub const NID_pkcs9_signingTime: c_int = 52;
|
||||
pub const NID_pkcs9_countersignature: c_int = 53;
|
||||
pub const NID_pkcs9_challengePassword: c_int = 54;
|
||||
pub const NID_pkcs9_unstructuredAddress: c_int = 55;
|
||||
pub const NID_pkcs9_extCertAttributes: c_int = 56;
|
||||
pub const NID_ext_req: c_int = 172;
|
||||
pub const NID_SMIMECapabilities: c_int = 167;
|
||||
pub const NID_SMIME: c_int = 188;
|
||||
pub const NID_id_smime_mod: c_int = 189;
|
||||
pub const NID_id_smime_ct: c_int = 190;
|
||||
pub const NID_id_smime_aa: c_int = 191;
|
||||
pub const NID_id_smime_alg: c_int = 192;
|
||||
pub const NID_id_smime_cd: c_int = 193;
|
||||
pub const NID_id_smime_spq: c_int = 194;
|
||||
pub const NID_id_smime_cti: c_int = 195;
|
||||
pub const NID_id_smime_mod_cms: c_int = 196;
|
||||
pub const NID_id_smime_mod_ess: c_int = 197;
|
||||
pub const NID_id_smime_mod_oid: c_int = 198;
|
||||
pub const NID_id_smime_mod_msg_v3: c_int = 199;
|
||||
pub const NID_id_smime_mod_ets_eSignature_88: c_int = 200;
|
||||
pub const NID_id_smime_mod_ets_eSignature_97: c_int = 201;
|
||||
pub const NID_id_smime_mod_ets_eSigPolicy_88: c_int = 202;
|
||||
pub const NID_id_smime_mod_ets_eSigPolicy_97: c_int = 203;
|
||||
pub const NID_id_smime_ct_receipt: c_int = 204;
|
||||
pub const NID_id_smime_ct_authData: c_int = 205;
|
||||
pub const NID_id_smime_ct_publishCert: c_int = 206;
|
||||
pub const NID_id_smime_ct_TSTInfo: c_int = 207;
|
||||
pub const NID_id_smime_ct_TDTInfo: c_int = 208;
|
||||
pub const NID_id_smime_ct_contentInfo: c_int = 209;
|
||||
pub const NID_id_smime_ct_DVCSRequestData: c_int = 210;
|
||||
pub const NID_id_smime_ct_DVCSResponseData: c_int = 211;
|
||||
pub const NID_id_smime_ct_compressedData: c_int = 786;
|
||||
pub const NID_id_ct_asciiTextWithCRLF: c_int = 787;
|
||||
pub const NID_id_smime_aa_receiptRequest: c_int = 212;
|
||||
pub const NID_id_smime_aa_securityLabel: c_int = 213;
|
||||
pub const NID_id_smime_aa_mlExpandHistory: c_int = 214;
|
||||
pub const NID_id_smime_aa_contentHint: c_int = 215;
|
||||
pub const NID_id_smime_aa_msgSigDigest: c_int = 216;
|
||||
pub const NID_id_smime_aa_encapContentType: c_int = 217;
|
||||
pub const NID_id_smime_aa_contentIdentifier: c_int = 218;
|
||||
pub const NID_id_smime_aa_macValue: c_int = 219;
|
||||
pub const NID_id_smime_aa_equivalentLabels: c_int = 220;
|
||||
pub const NID_id_smime_aa_contentReference: c_int = 221;
|
||||
pub const NID_id_smime_aa_encrypKeyPref: c_int = 222;
|
||||
pub const NID_id_smime_aa_signingCertificate: c_int = 223;
|
||||
pub const NID_id_smime_aa_smimeEncryptCerts: c_int = 224;
|
||||
pub const NID_id_smime_aa_timeStampToken: c_int = 225;
|
||||
pub const NID_id_smime_aa_ets_sigPolicyId: c_int = 226;
|
||||
pub const NID_id_smime_aa_ets_commitmentType: c_int = 227;
|
||||
pub const NID_id_smime_aa_ets_signerLocation: c_int = 228;
|
||||
pub const NID_id_smime_aa_ets_signerAttr: c_int = 229;
|
||||
pub const NID_id_smime_aa_ets_otherSigCert: c_int = 230;
|
||||
pub const NID_id_smime_aa_ets_contentTimestamp: c_int = 231;
|
||||
pub const NID_id_smime_aa_ets_CertificateRefs: c_int = 232;
|
||||
pub const NID_id_smime_aa_ets_RevocationRefs: c_int = 233;
|
||||
pub const NID_id_smime_aa_ets_certValues: c_int = 234;
|
||||
pub const NID_id_smime_aa_ets_revocationValues: c_int = 235;
|
||||
pub const NID_id_smime_aa_ets_escTimeStamp: c_int = 236;
|
||||
pub const NID_id_smime_aa_ets_certCRLTimestamp: c_int = 237;
|
||||
pub const NID_id_smime_aa_ets_archiveTimeStamp: c_int = 238;
|
||||
pub const NID_id_smime_aa_signatureType: c_int = 239;
|
||||
pub const NID_id_smime_aa_dvcs_dvc: c_int = 240;
|
||||
pub const NID_id_smime_alg_ESDHwith3DES: c_int = 241;
|
||||
pub const NID_id_smime_alg_ESDHwithRC2: c_int = 242;
|
||||
pub const NID_id_smime_alg_3DESwrap: c_int = 243;
|
||||
pub const NID_id_smime_alg_RC2wrap: c_int = 244;
|
||||
pub const NID_id_smime_alg_ESDH: c_int = 245;
|
||||
pub const NID_id_smime_alg_CMS3DESwrap: c_int = 246;
|
||||
pub const NID_id_smime_alg_CMSRC2wrap: c_int = 247;
|
||||
pub const NID_id_alg_PWRI_KEK: c_int = 893;
|
||||
pub const NID_id_smime_cd_ldap: c_int = 248;
|
||||
pub const NID_id_smime_spq_ets_sqt_uri: c_int = 249;
|
||||
pub const NID_id_smime_spq_ets_sqt_unotice: c_int = 250;
|
||||
pub const NID_id_smime_cti_ets_proofOfOrigin: c_int = 251;
|
||||
pub const NID_id_smime_cti_ets_proofOfReceipt: c_int = 252;
|
||||
pub const NID_id_smime_cti_ets_proofOfDelivery: c_int = 253;
|
||||
pub const NID_id_smime_cti_ets_proofOfSender: c_int = 254;
|
||||
pub const NID_id_smime_cti_ets_proofOfApproval: c_int = 255;
|
||||
pub const NID_id_smime_cti_ets_proofOfCreation: c_int = 256;
|
||||
pub const NID_friendlyName: c_int = 156;
|
||||
pub const NID_localKeyID: c_int = 157;
|
||||
pub const NID_ms_csp_name: c_int = 417;
|
||||
pub const NID_LocalKeySet: c_int = 856;
|
||||
pub const NID_x509Certificate: c_int = 158;
|
||||
pub const NID_sdsiCertificate: c_int = 159;
|
||||
pub const NID_x509Crl: c_int = 160;
|
||||
pub const NID_pbe_WithSHA1And128BitRC4: c_int = 144;
|
||||
pub const NID_pbe_WithSHA1And40BitRC4: c_int = 145;
|
||||
pub const NID_pbe_WithSHA1And3_Key_TripleDES_CBC: c_int = 146;
|
||||
pub const NID_pbe_WithSHA1And2_Key_TripleDES_CBC: c_int = 147;
|
||||
pub const NID_pbe_WithSHA1And128BitRC2_CBC: c_int = 148;
|
||||
pub const NID_pbe_WithSHA1And40BitRC2_CBC: c_int = 149;
|
||||
pub const NID_keyBag: c_int = 150;
|
||||
pub const NID_pkcs8ShroudedKeyBag: c_int = 151;
|
||||
pub const NID_certBag: c_int = 152;
|
||||
pub const NID_crlBag: c_int = 153;
|
||||
pub const NID_secretBag: c_int = 154;
|
||||
pub const NID_safeContentsBag: c_int = 155;
|
||||
pub const NID_md2: c_int = 3;
|
||||
pub const NID_md4: c_int = 257;
|
||||
pub const NID_md5: c_int = 4;
|
||||
pub const NID_md5_sha1: c_int = 114;
|
||||
pub const NID_hmacWithMD5: c_int = 797;
|
||||
pub const NID_hmacWithSHA1: c_int = 163;
|
||||
pub const NID_hmacWithSHA224: c_int = 798;
|
||||
pub const NID_hmacWithSHA256: c_int = 799;
|
||||
pub const NID_hmacWithSHA384: c_int = 800;
|
||||
pub const NID_hmacWithSHA512: c_int = 801;
|
||||
pub const NID_rc2_cbc: c_int = 37;
|
||||
pub const NID_rc2_ecb: c_int = 38;
|
||||
pub const NID_rc2_cfb64: c_int = 39;
|
||||
pub const NID_rc2_ofb64: c_int = 40;
|
||||
pub const NID_rc2_40_cbc: c_int = 98;
|
||||
pub const NID_rc2_64_cbc: c_int = 166;
|
||||
pub const NID_rc4: c_int = 5;
|
||||
pub const NID_rc4_40: c_int = 97;
|
||||
pub const NID_des_ede3_cbc: c_int = 44;
|
||||
pub const NID_rc5_cbc: c_int = 120;
|
||||
pub const NID_rc5_ecb: c_int = 121;
|
||||
pub const NID_rc5_cfb64: c_int = 122;
|
||||
pub const NID_rc5_ofb64: c_int = 123;
|
||||
pub const NID_ms_ext_req: c_int = 171;
|
||||
pub const NID_ms_code_ind: c_int = 134;
|
||||
pub const NID_ms_code_com: c_int = 135;
|
||||
pub const NID_ms_ctl_sign: c_int = 136;
|
||||
pub const NID_ms_sgc: c_int = 137;
|
||||
pub const NID_ms_efs: c_int = 138;
|
||||
pub const NID_ms_smartcard_login: c_int = 648;
|
||||
pub const NID_ms_upn: c_int = 649;
|
||||
pub const NID_idea_cbc: c_int = 34;
|
||||
pub const NID_idea_ecb: c_int = 36;
|
||||
pub const NID_idea_cfb64: c_int = 35;
|
||||
pub const NID_idea_ofb64: c_int = 46;
|
||||
pub const NID_bf_cbc: c_int = 91;
|
||||
pub const NID_bf_ecb: c_int = 92;
|
||||
pub const NID_bf_cfb64: c_int = 93;
|
||||
pub const NID_bf_ofb64: c_int = 94;
|
||||
pub const NID_id_pkix: c_int = 127;
|
||||
pub const NID_id_pkix_mod: c_int = 258;
|
||||
pub const NID_id_pe: c_int = 175;
|
||||
pub const NID_id_qt: c_int = 259;
|
||||
pub const NID_id_kp: c_int = 128;
|
||||
pub const NID_id_it: c_int = 260;
|
||||
pub const NID_id_pkip: c_int = 261;
|
||||
pub const NID_id_alg: c_int = 262;
|
||||
pub const NID_id_cmc: c_int = 263;
|
||||
pub const NID_id_on: c_int = 264;
|
||||
pub const NID_id_pda: c_int = 265;
|
||||
pub const NID_id_aca: c_int = 266;
|
||||
pub const NID_id_qcs: c_int = 267;
|
||||
pub const NID_id_cct: c_int = 268;
|
||||
pub const NID_id_ppl: c_int = 662;
|
||||
pub const NID_id_ad: c_int = 176;
|
||||
pub const NID_id_pkix1_explicit_88: c_int = 269;
|
||||
pub const NID_id_pkix1_implicit_88: c_int = 270;
|
||||
pub const NID_id_pkix1_explicit_93: c_int = 271;
|
||||
pub const NID_id_pkix1_implicit_93: c_int = 272;
|
||||
pub const NID_id_mod_crmf: c_int = 273;
|
||||
pub const NID_id_mod_cmc: c_int = 274;
|
||||
pub const NID_id_mod_kea_profile_88: c_int = 275;
|
||||
pub const NID_id_mod_kea_profile_93: c_int = 276;
|
||||
pub const NID_id_mod_cmp: c_int = 277;
|
||||
pub const NID_id_mod_qualified_cert_88: c_int = 278;
|
||||
pub const NID_id_mod_qualified_cert_93: c_int = 279;
|
||||
pub const NID_id_mod_attribute_cert: c_int = 280;
|
||||
pub const NID_id_mod_timestamp_protocol: c_int = 281;
|
||||
pub const NID_id_mod_ocsp: c_int = 282;
|
||||
pub const NID_id_mod_dvcs: c_int = 283;
|
||||
pub const NID_id_mod_cmp2000: c_int = 284;
|
||||
pub const NID_info_access: c_int = 177;
|
||||
pub const NID_biometricInfo: c_int = 285;
|
||||
pub const NID_qcStatements: c_int = 286;
|
||||
pub const NID_ac_auditEntity: c_int = 287;
|
||||
pub const NID_ac_targeting: c_int = 288;
|
||||
pub const NID_aaControls: c_int = 289;
|
||||
pub const NID_sbgp_ipAddrBlock: c_int = 290;
|
||||
pub const NID_sbgp_autonomousSysNum: c_int = 291;
|
||||
pub const NID_sbgp_routerIdentifier: c_int = 292;
|
||||
pub const NID_ac_proxying: c_int = 397;
|
||||
pub const NID_sinfo_access: c_int = 398;
|
||||
pub const NID_proxyCertInfo: c_int = 663;
|
||||
pub const NID_id_qt_cps: c_int = 164;
|
||||
pub const NID_id_qt_unotice: c_int = 165;
|
||||
pub const NID_textNotice: c_int = 293;
|
||||
pub const NID_server_auth: c_int = 129;
|
||||
pub const NID_client_auth: c_int = 130;
|
||||
pub const NID_code_sign: c_int = 131;
|
||||
pub const NID_email_protect: c_int = 132;
|
||||
pub const NID_ipsecEndSystem: c_int = 294;
|
||||
pub const NID_ipsecTunnel: c_int = 295;
|
||||
pub const NID_ipsecUser: c_int = 296;
|
||||
pub const NID_time_stamp: c_int = 133;
|
||||
pub const NID_OCSP_sign: c_int = 180;
|
||||
pub const NID_dvcs: c_int = 297;
|
||||
pub const NID_id_it_caProtEncCert: c_int = 298;
|
||||
pub const NID_id_it_signKeyPairTypes: c_int = 299;
|
||||
pub const NID_id_it_encKeyPairTypes: c_int = 300;
|
||||
pub const NID_id_it_preferredSymmAlg: c_int = 301;
|
||||
pub const NID_id_it_caKeyUpdateInfo: c_int = 302;
|
||||
pub const NID_id_it_currentCRL: c_int = 303;
|
||||
pub const NID_id_it_unsupportedOIDs: c_int = 304;
|
||||
pub const NID_id_it_subscriptionRequest: c_int = 305;
|
||||
pub const NID_id_it_subscriptionResponse: c_int = 306;
|
||||
pub const NID_id_it_keyPairParamReq: c_int = 307;
|
||||
pub const NID_id_it_keyPairParamRep: c_int = 308;
|
||||
pub const NID_id_it_revPassphrase: c_int = 309;
|
||||
pub const NID_id_it_implicitConfirm: c_int = 310;
|
||||
pub const NID_id_it_confirmWaitTime: c_int = 311;
|
||||
pub const NID_id_it_origPKIMessage: c_int = 312;
|
||||
pub const NID_id_it_suppLangTags: c_int = 784;
|
||||
pub const NID_id_regCtrl: c_int = 313;
|
||||
pub const NID_id_regInfo: c_int = 314;
|
||||
pub const NID_id_regCtrl_regToken: c_int = 315;
|
||||
pub const NID_id_regCtrl_authenticator: c_int = 316;
|
||||
pub const NID_id_regCtrl_pkiPublicationInfo: c_int = 317;
|
||||
pub const NID_id_regCtrl_pkiArchiveOptions: c_int = 318;
|
||||
pub const NID_id_regCtrl_oldCertID: c_int = 319;
|
||||
pub const NID_id_regCtrl_protocolEncrKey: c_int = 320;
|
||||
pub const NID_id_regInfo_utf8Pairs: c_int = 321;
|
||||
pub const NID_id_regInfo_certReq: c_int = 322;
|
||||
pub const NID_id_alg_des40: c_int = 323;
|
||||
pub const NID_id_alg_noSignature: c_int = 324;
|
||||
pub const NID_id_alg_dh_sig_hmac_sha1: c_int = 325;
|
||||
pub const NID_id_alg_dh_pop: c_int = 326;
|
||||
pub const NID_id_cmc_statusInfo: c_int = 327;
|
||||
pub const NID_id_cmc_identification: c_int = 328;
|
||||
pub const NID_id_cmc_identityProof: c_int = 329;
|
||||
pub const NID_id_cmc_dataReturn: c_int = 330;
|
||||
pub const NID_id_cmc_transactionId: c_int = 331;
|
||||
pub const NID_id_cmc_senderNonce: c_int = 332;
|
||||
pub const NID_id_cmc_recipientNonce: c_int = 333;
|
||||
pub const NID_id_cmc_addExtensions: c_int = 334;
|
||||
pub const NID_id_cmc_encryptedPOP: c_int = 335;
|
||||
pub const NID_id_cmc_decryptedPOP: c_int = 336;
|
||||
pub const NID_id_cmc_lraPOPWitness: c_int = 337;
|
||||
pub const NID_id_cmc_getCert: c_int = 338;
|
||||
pub const NID_id_cmc_getCRL: c_int = 339;
|
||||
pub const NID_id_cmc_revokeRequest: c_int = 340;
|
||||
pub const NID_id_cmc_regInfo: c_int = 341;
|
||||
pub const NID_id_cmc_responseInfo: c_int = 342;
|
||||
pub const NID_id_cmc_queryPending: c_int = 343;
|
||||
pub const NID_id_cmc_popLinkRandom: c_int = 344;
|
||||
pub const NID_id_cmc_popLinkWitness: c_int = 345;
|
||||
pub const NID_id_cmc_confirmCertAcceptance: c_int = 346;
|
||||
pub const NID_id_on_personalData: c_int = 347;
|
||||
pub const NID_id_on_permanentIdentifier: c_int = 858;
|
||||
pub const NID_id_pda_dateOfBirth: c_int = 348;
|
||||
pub const NID_id_pda_placeOfBirth: c_int = 349;
|
||||
pub const NID_id_pda_gender: c_int = 351;
|
||||
pub const NID_id_pda_countryOfCitizenship: c_int = 352;
|
||||
pub const NID_id_pda_countryOfResidence: c_int = 353;
|
||||
pub const NID_id_aca_authenticationInfo: c_int = 354;
|
||||
pub const NID_id_aca_accessIdentity: c_int = 355;
|
||||
pub const NID_id_aca_chargingIdentity: c_int = 356;
|
||||
pub const NID_id_aca_group: c_int = 357;
|
||||
pub const NID_id_aca_role: c_int = 358;
|
||||
pub const NID_id_aca_encAttrs: c_int = 399;
|
||||
pub const NID_id_qcs_pkixQCSyntax_v1: c_int = 359;
|
||||
pub const NID_id_cct_crs: c_int = 360;
|
||||
pub const NID_id_cct_PKIData: c_int = 361;
|
||||
pub const NID_id_cct_PKIResponse: c_int = 362;
|
||||
pub const NID_id_ppl_anyLanguage: c_int = 664;
|
||||
pub const NID_id_ppl_inheritAll: c_int = 665;
|
||||
pub const NID_Independent: c_int = 667;
|
||||
pub const NID_ad_OCSP: c_int = 178;
|
||||
pub const NID_ad_ca_issuers: c_int = 179;
|
||||
pub const NID_ad_timeStamping: c_int = 363;
|
||||
pub const NID_ad_dvcs: c_int = 364;
|
||||
pub const NID_caRepository: c_int = 785;
|
||||
pub const NID_id_pkix_OCSP_basic: c_int = 365;
|
||||
pub const NID_id_pkix_OCSP_Nonce: c_int = 366;
|
||||
pub const NID_id_pkix_OCSP_CrlID: c_int = 367;
|
||||
pub const NID_id_pkix_OCSP_acceptableResponses: c_int = 368;
|
||||
pub const NID_id_pkix_OCSP_noCheck: c_int = 369;
|
||||
pub const NID_id_pkix_OCSP_archiveCutoff: c_int = 370;
|
||||
pub const NID_id_pkix_OCSP_serviceLocator: c_int = 371;
|
||||
pub const NID_id_pkix_OCSP_extendedStatus: c_int = 372;
|
||||
pub const NID_id_pkix_OCSP_valid: c_int = 373;
|
||||
pub const NID_id_pkix_OCSP_path: c_int = 374;
|
||||
pub const NID_id_pkix_OCSP_trustRoot: c_int = 375;
|
||||
pub const NID_algorithm: c_int = 376;
|
||||
pub const NID_md5WithRSA: c_int = 104;
|
||||
pub const NID_des_ecb: c_int = 29;
|
||||
pub const NID_des_cbc: c_int = 31;
|
||||
pub const NID_des_ofb64: c_int = 45;
|
||||
pub const NID_des_cfb64: c_int = 30;
|
||||
pub const NID_rsaSignature: c_int = 377;
|
||||
pub const NID_dsa_2: c_int = 67;
|
||||
pub const NID_dsaWithSHA: c_int = 66;
|
||||
pub const NID_shaWithRSAEncryption: c_int = 42;
|
||||
pub const NID_des_ede_ecb: c_int = 32;
|
||||
pub const NID_des_ede3_ecb: c_int = 33;
|
||||
pub const NID_des_ede_cbc: c_int = 43;
|
||||
pub const NID_des_ede_cfb64: c_int = 60;
|
||||
pub const NID_des_ede3_cfb64: c_int = 61;
|
||||
pub const NID_des_ede_ofb64: c_int = 62;
|
||||
pub const NID_des_ede3_ofb64: c_int = 63;
|
||||
pub const NID_desx_cbc: c_int = 80;
|
||||
pub const NID_sha: c_int = 41;
|
||||
pub const NID_sha1: c_int = 64;
|
||||
pub const NID_dsaWithSHA1_2: c_int = 70;
|
||||
pub const NID_sha1WithRSA: c_int = 115;
|
||||
pub const NID_ripemd160: c_int = 117;
|
||||
pub const NID_ripemd160WithRSA: c_int = 119;
|
||||
pub const NID_sxnet: c_int = 143;
|
||||
pub const NID_X500: c_int = 11;
|
||||
pub const NID_X509: c_int = 12;
|
||||
pub const NID_commonName: c_int = 13;
|
||||
pub const NID_surname: c_int = 100;
|
||||
pub const NID_serialNumber: c_int = 105;
|
||||
pub const NID_countryName: c_int = 14;
|
||||
pub const NID_localityName: c_int = 15;
|
||||
pub const NID_stateOrProvinceName: c_int = 16;
|
||||
pub const NID_streetAddress: c_int = 660;
|
||||
pub const NID_organizationName: c_int = 17;
|
||||
pub const NID_organizationalUnitName: c_int = 18;
|
||||
pub const NID_title: c_int = 106;
|
||||
pub const NID_description: c_int = 107;
|
||||
pub const NID_searchGuide: c_int = 859;
|
||||
pub const NID_businessCategory: c_int = 860;
|
||||
pub const NID_postalAddress: c_int = 861;
|
||||
pub const NID_postalCode: c_int = 661;
|
||||
pub const NID_postOfficeBox: c_int = 862;
|
||||
pub const NID_physicalDeliveryOfficeName: c_int = 863;
|
||||
pub const NID_telephoneNumber: c_int = 864;
|
||||
pub const NID_telexNumber: c_int = 865;
|
||||
pub const NID_teletexTerminalIdentifier: c_int = 866;
|
||||
pub const NID_facsimileTelephoneNumber: c_int = 867;
|
||||
pub const NID_x121Address: c_int = 868;
|
||||
pub const NID_internationaliSDNNumber: c_int = 869;
|
||||
pub const NID_registeredAddress: c_int = 870;
|
||||
pub const NID_destinationIndicator: c_int = 871;
|
||||
pub const NID_preferredDeliveryMethod: c_int = 872;
|
||||
pub const NID_presentationAddress: c_int = 873;
|
||||
pub const NID_supportedApplicationContext: c_int = 874;
|
||||
pub const NID_member: c_int = 875;
|
||||
pub const NID_owner: c_int = 876;
|
||||
pub const NID_roleOccupant: c_int = 877;
|
||||
pub const NID_seeAlso: c_int = 878;
|
||||
pub const NID_userPassword: c_int = 879;
|
||||
pub const NID_userCertificate: c_int = 880;
|
||||
pub const NID_cACertificate: c_int = 881;
|
||||
pub const NID_authorityRevocationList: c_int = 882;
|
||||
pub const NID_certificateRevocationList: c_int = 883;
|
||||
pub const NID_crossCertificatePair: c_int = 884;
|
||||
pub const NID_name: c_int = 173;
|
||||
pub const NID_givenName: c_int = 99;
|
||||
pub const NID_initials: c_int = 101;
|
||||
pub const NID_generationQualifier: c_int = 509;
|
||||
pub const NID_x500UniqueIdentifier: c_int = 503;
|
||||
pub const NID_dnQualifier: c_int = 174;
|
||||
pub const NID_enhancedSearchGuide: c_int = 885;
|
||||
pub const NID_protocolInformation: c_int = 886;
|
||||
pub const NID_distinguishedName: c_int = 887;
|
||||
pub const NID_uniqueMember: c_int = 888;
|
||||
pub const NID_houseIdentifier: c_int = 889;
|
||||
pub const NID_supportedAlgorithms: c_int = 890;
|
||||
pub const NID_deltaRevocationList: c_int = 891;
|
||||
pub const NID_dmdName: c_int = 892;
|
||||
pub const NID_pseudonym: c_int = 510;
|
||||
pub const NID_role: c_int = 400;
|
||||
pub const NID_X500algorithms: c_int = 378;
|
||||
pub const NID_rsa: c_int = 19;
|
||||
pub const NID_mdc2WithRSA: c_int = 96;
|
||||
pub const NID_mdc2: c_int = 95;
|
||||
pub const NID_id_ce: c_int = 81;
|
||||
pub const NID_subject_directory_attributes: c_int = 769;
|
||||
pub const NID_subject_key_identifier: c_int = 82;
|
||||
pub const NID_key_usage: c_int = 83;
|
||||
pub const NID_private_key_usage_period: c_int = 84;
|
||||
pub const NID_subject_alt_name: c_int = 85;
|
||||
pub const NID_issuer_alt_name: c_int = 86;
|
||||
pub const NID_basic_constraints: c_int = 87;
|
||||
pub const NID_crl_number: c_int = 88;
|
||||
pub const NID_crl_reason: c_int = 141;
|
||||
pub const NID_invalidity_date: c_int = 142;
|
||||
pub const NID_delta_crl: c_int = 140;
|
||||
pub const NID_issuing_distribution_point: c_int = 770;
|
||||
pub const NID_certificate_issuer: c_int = 771;
|
||||
pub const NID_name_constraints: c_int = 666;
|
||||
pub const NID_crl_distribution_points: c_int = 103;
|
||||
pub const NID_certificate_policies: c_int = 89;
|
||||
pub const NID_any_policy: c_int = 746;
|
||||
pub const NID_policy_mappings: c_int = 747;
|
||||
pub const NID_authority_key_identifier: c_int = 90;
|
||||
pub const NID_policy_constraints: c_int = 401;
|
||||
pub const NID_ext_key_usage: c_int = 126;
|
||||
pub const NID_freshest_crl: c_int = 857;
|
||||
pub const NID_inhibit_any_policy: c_int = 748;
|
||||
pub const NID_target_information: c_int = 402;
|
||||
pub const NID_no_rev_avail: c_int = 403;
|
||||
pub const NID_anyExtendedKeyUsage: c_int = 910;
|
||||
pub const NID_netscape: c_int = 57;
|
||||
pub const NID_netscape_cert_extension: c_int = 58;
|
||||
pub const NID_netscape_data_type: c_int = 59;
|
||||
pub const NID_netscape_cert_type: c_int = 71;
|
||||
pub const NID_netscape_base_url: c_int = 72;
|
||||
pub const NID_netscape_revocation_url: c_int = 73;
|
||||
pub const NID_netscape_ca_revocation_url: c_int = 74;
|
||||
pub const NID_netscape_renewal_url: c_int = 75;
|
||||
pub const NID_netscape_ca_policy_url: c_int = 76;
|
||||
pub const NID_netscape_ssl_server_name: c_int = 77;
|
||||
pub const NID_netscape_comment: c_int = 78;
|
||||
pub const NID_netscape_cert_sequence: c_int = 79;
|
||||
pub const NID_ns_sgc: c_int = 139;
|
||||
pub const NID_org: c_int = 379;
|
||||
pub const NID_dod: c_int = 380;
|
||||
pub const NID_iana: c_int = 381;
|
||||
pub const NID_Directory: c_int = 382;
|
||||
pub const NID_Management: c_int = 383;
|
||||
pub const NID_Experimental: c_int = 384;
|
||||
pub const NID_Private: c_int = 385;
|
||||
pub const NID_Security: c_int = 386;
|
||||
pub const NID_SNMPv2: c_int = 387;
|
||||
pub const NID_Mail: c_int = 388;
|
||||
pub const NID_Enterprises: c_int = 389;
|
||||
pub const NID_dcObject: c_int = 390;
|
||||
pub const NID_mime_mhs: c_int = 504;
|
||||
pub const NID_mime_mhs_headings: c_int = 505;
|
||||
pub const NID_mime_mhs_bodies: c_int = 506;
|
||||
pub const NID_id_hex_partial_message: c_int = 507;
|
||||
pub const NID_id_hex_multipart_message: c_int = 508;
|
||||
pub const NID_zlib_compression: c_int = 125;
|
||||
pub const NID_aes_128_ecb: c_int = 418;
|
||||
pub const NID_aes_128_cbc: c_int = 419;
|
||||
pub const NID_aes_128_ofb128: c_int = 420;
|
||||
pub const NID_aes_128_cfb128: c_int = 421;
|
||||
pub const NID_id_aes128_wrap: c_int = 788;
|
||||
pub const NID_aes_128_gcm: c_int = 895;
|
||||
pub const NID_aes_128_ccm: c_int = 896;
|
||||
pub const NID_id_aes128_wrap_pad: c_int = 897;
|
||||
pub const NID_aes_192_ecb: c_int = 422;
|
||||
pub const NID_aes_192_cbc: c_int = 423;
|
||||
pub const NID_aes_192_ofb128: c_int = 424;
|
||||
pub const NID_aes_192_cfb128: c_int = 425;
|
||||
pub const NID_id_aes192_wrap: c_int = 789;
|
||||
pub const NID_aes_192_gcm: c_int = 898;
|
||||
pub const NID_aes_192_ccm: c_int = 899;
|
||||
pub const NID_id_aes192_wrap_pad: c_int = 900;
|
||||
pub const NID_aes_256_ecb: c_int = 426;
|
||||
pub const NID_aes_256_cbc: c_int = 427;
|
||||
pub const NID_aes_256_ofb128: c_int = 428;
|
||||
pub const NID_aes_256_cfb128: c_int = 429;
|
||||
pub const NID_id_aes256_wrap: c_int = 790;
|
||||
pub const NID_aes_256_gcm: c_int = 901;
|
||||
pub const NID_aes_256_ccm: c_int = 902;
|
||||
pub const NID_id_aes256_wrap_pad: c_int = 903;
|
||||
pub const NID_aes_128_cfb1: c_int = 650;
|
||||
pub const NID_aes_192_cfb1: c_int = 651;
|
||||
pub const NID_aes_256_cfb1: c_int = 652;
|
||||
pub const NID_aes_128_cfb8: c_int = 653;
|
||||
pub const NID_aes_192_cfb8: c_int = 654;
|
||||
pub const NID_aes_256_cfb8: c_int = 655;
|
||||
pub const NID_aes_128_ctr: c_int = 904;
|
||||
pub const NID_aes_192_ctr: c_int = 905;
|
||||
pub const NID_aes_256_ctr: c_int = 906;
|
||||
pub const NID_aes_128_xts: c_int = 913;
|
||||
pub const NID_aes_256_xts: c_int = 914;
|
||||
pub const NID_des_cfb1: c_int = 656;
|
||||
pub const NID_des_cfb8: c_int = 657;
|
||||
pub const NID_des_ede3_cfb1: c_int = 658;
|
||||
pub const NID_des_ede3_cfb8: c_int = 659;
|
||||
pub const NID_sha256: c_int = 672;
|
||||
pub const NID_sha384: c_int = 673;
|
||||
pub const NID_sha512: c_int = 674;
|
||||
pub const NID_sha224: c_int = 675;
|
||||
pub const NID_dsa_with_SHA224: c_int = 802;
|
||||
pub const NID_dsa_with_SHA256: c_int = 803;
|
||||
pub const NID_hold_instruction_code: c_int = 430;
|
||||
pub const NID_hold_instruction_none: c_int = 431;
|
||||
pub const NID_hold_instruction_call_issuer: c_int = 432;
|
||||
pub const NID_hold_instruction_reject: c_int = 433;
|
||||
pub const NID_data: c_int = 434;
|
||||
pub const NID_pss: c_int = 435;
|
||||
pub const NID_ucl: c_int = 436;
|
||||
pub const NID_pilot: c_int = 437;
|
||||
pub const NID_pilotAttributeType: c_int = 438;
|
||||
pub const NID_pilotAttributeSyntax: c_int = 439;
|
||||
pub const NID_pilotObjectClass: c_int = 440;
|
||||
pub const NID_pilotGroups: c_int = 441;
|
||||
pub const NID_iA5StringSyntax: c_int = 442;
|
||||
pub const NID_caseIgnoreIA5StringSyntax: c_int = 443;
|
||||
pub const NID_pilotObject: c_int = 444;
|
||||
pub const NID_pilotPerson: c_int = 445;
|
||||
pub const NID_account: c_int = 446;
|
||||
pub const NID_document: c_int = 447;
|
||||
pub const NID_room: c_int = 448;
|
||||
pub const NID_documentSeries: c_int = 449;
|
||||
pub const NID_Domain: c_int = 392;
|
||||
pub const NID_rFC822localPart: c_int = 450;
|
||||
pub const NID_dNSDomain: c_int = 451;
|
||||
pub const NID_domainRelatedObject: c_int = 452;
|
||||
pub const NID_friendlyCountry: c_int = 453;
|
||||
pub const NID_simpleSecurityObject: c_int = 454;
|
||||
pub const NID_pilotOrganization: c_int = 455;
|
||||
pub const NID_pilotDSA: c_int = 456;
|
||||
pub const NID_qualityLabelledData: c_int = 457;
|
||||
pub const NID_userId: c_int = 458;
|
||||
pub const NID_textEncodedORAddress: c_int = 459;
|
||||
pub const NID_rfc822Mailbox: c_int = 460;
|
||||
pub const NID_info: c_int = 461;
|
||||
pub const NID_favouriteDrink: c_int = 462;
|
||||
pub const NID_roomNumber: c_int = 463;
|
||||
pub const NID_photo: c_int = 464;
|
||||
pub const NID_userClass: c_int = 465;
|
||||
pub const NID_host: c_int = 466;
|
||||
pub const NID_manager: c_int = 467;
|
||||
pub const NID_documentIdentifier: c_int = 468;
|
||||
pub const NID_documentTitle: c_int = 469;
|
||||
pub const NID_documentVersion: c_int = 470;
|
||||
pub const NID_documentAuthor: c_int = 471;
|
||||
pub const NID_documentLocation: c_int = 472;
|
||||
pub const NID_homeTelephoneNumber: c_int = 473;
|
||||
pub const NID_secretary: c_int = 474;
|
||||
pub const NID_otherMailbox: c_int = 475;
|
||||
pub const NID_lastModifiedTime: c_int = 476;
|
||||
pub const NID_lastModifiedBy: c_int = 477;
|
||||
pub const NID_domainComponent: c_int = 391;
|
||||
pub const NID_aRecord: c_int = 478;
|
||||
pub const NID_pilotAttributeType27: c_int = 479;
|
||||
pub const NID_mXRecord: c_int = 480;
|
||||
pub const NID_nSRecord: c_int = 481;
|
||||
pub const NID_sOARecord: c_int = 482;
|
||||
pub const NID_cNAMERecord: c_int = 483;
|
||||
pub const NID_associatedDomain: c_int = 484;
|
||||
pub const NID_associatedName: c_int = 485;
|
||||
pub const NID_homePostalAddress: c_int = 486;
|
||||
pub const NID_personalTitle: c_int = 487;
|
||||
pub const NID_mobileTelephoneNumber: c_int = 488;
|
||||
pub const NID_pagerTelephoneNumber: c_int = 489;
|
||||
pub const NID_friendlyCountryName: c_int = 490;
|
||||
pub const NID_organizationalStatus: c_int = 491;
|
||||
pub const NID_janetMailbox: c_int = 492;
|
||||
pub const NID_mailPreferenceOption: c_int = 493;
|
||||
pub const NID_buildingName: c_int = 494;
|
||||
pub const NID_dSAQuality: c_int = 495;
|
||||
pub const NID_singleLevelQuality: c_int = 496;
|
||||
pub const NID_subtreeMinimumQuality: c_int = 497;
|
||||
pub const NID_subtreeMaximumQuality: c_int = 498;
|
||||
pub const NID_personalSignature: c_int = 499;
|
||||
pub const NID_dITRedirect: c_int = 500;
|
||||
pub const NID_audio: c_int = 501;
|
||||
pub const NID_documentPublisher: c_int = 502;
|
||||
pub const NID_id_set: c_int = 512;
|
||||
pub const NID_set_ctype: c_int = 513;
|
||||
pub const NID_set_msgExt: c_int = 514;
|
||||
pub const NID_set_attr: c_int = 515;
|
||||
pub const NID_set_policy: c_int = 516;
|
||||
pub const NID_set_certExt: c_int = 517;
|
||||
pub const NID_set_brand: c_int = 518;
|
||||
pub const NID_setct_PANData: c_int = 519;
|
||||
pub const NID_setct_PANToken: c_int = 520;
|
||||
pub const NID_setct_PANOnly: c_int = 521;
|
||||
pub const NID_setct_OIData: c_int = 522;
|
||||
pub const NID_setct_PI: c_int = 523;
|
||||
pub const NID_setct_PIData: c_int = 524;
|
||||
pub const NID_setct_PIDataUnsigned: c_int = 525;
|
||||
pub const NID_setct_HODInput: c_int = 526;
|
||||
pub const NID_setct_AuthResBaggage: c_int = 527;
|
||||
pub const NID_setct_AuthRevReqBaggage: c_int = 528;
|
||||
pub const NID_setct_AuthRevResBaggage: c_int = 529;
|
||||
pub const NID_setct_CapTokenSeq: c_int = 530;
|
||||
pub const NID_setct_PInitResData: c_int = 531;
|
||||
pub const NID_setct_PI_TBS: c_int = 532;
|
||||
pub const NID_setct_PResData: c_int = 533;
|
||||
pub const NID_setct_AuthReqTBS: c_int = 534;
|
||||
pub const NID_setct_AuthResTBS: c_int = 535;
|
||||
pub const NID_setct_AuthResTBSX: c_int = 536;
|
||||
pub const NID_setct_AuthTokenTBS: c_int = 537;
|
||||
pub const NID_setct_CapTokenData: c_int = 538;
|
||||
pub const NID_setct_CapTokenTBS: c_int = 539;
|
||||
pub const NID_setct_AcqCardCodeMsg: c_int = 540;
|
||||
pub const NID_setct_AuthRevReqTBS: c_int = 541;
|
||||
pub const NID_setct_AuthRevResData: c_int = 542;
|
||||
pub const NID_setct_AuthRevResTBS: c_int = 543;
|
||||
pub const NID_setct_CapReqTBS: c_int = 544;
|
||||
pub const NID_setct_CapReqTBSX: c_int = 545;
|
||||
pub const NID_setct_CapResData: c_int = 546;
|
||||
pub const NID_setct_CapRevReqTBS: c_int = 547;
|
||||
pub const NID_setct_CapRevReqTBSX: c_int = 548;
|
||||
pub const NID_setct_CapRevResData: c_int = 549;
|
||||
pub const NID_setct_CredReqTBS: c_int = 550;
|
||||
pub const NID_setct_CredReqTBSX: c_int = 551;
|
||||
pub const NID_setct_CredResData: c_int = 552;
|
||||
pub const NID_setct_CredRevReqTBS: c_int = 553;
|
||||
pub const NID_setct_CredRevReqTBSX: c_int = 554;
|
||||
pub const NID_setct_CredRevResData: c_int = 555;
|
||||
pub const NID_setct_PCertReqData: c_int = 556;
|
||||
pub const NID_setct_PCertResTBS: c_int = 557;
|
||||
pub const NID_setct_BatchAdminReqData: c_int = 558;
|
||||
pub const NID_setct_BatchAdminResData: c_int = 559;
|
||||
pub const NID_setct_CardCInitResTBS: c_int = 560;
|
||||
pub const NID_setct_MeAqCInitResTBS: c_int = 561;
|
||||
pub const NID_setct_RegFormResTBS: c_int = 562;
|
||||
pub const NID_setct_CertReqData: c_int = 563;
|
||||
pub const NID_setct_CertReqTBS: c_int = 564;
|
||||
pub const NID_setct_CertResData: c_int = 565;
|
||||
pub const NID_setct_CertInqReqTBS: c_int = 566;
|
||||
pub const NID_setct_ErrorTBS: c_int = 567;
|
||||
pub const NID_setct_PIDualSignedTBE: c_int = 568;
|
||||
pub const NID_setct_PIUnsignedTBE: c_int = 569;
|
||||
pub const NID_setct_AuthReqTBE: c_int = 570;
|
||||
pub const NID_setct_AuthResTBE: c_int = 571;
|
||||
pub const NID_setct_AuthResTBEX: c_int = 572;
|
||||
pub const NID_setct_AuthTokenTBE: c_int = 573;
|
||||
pub const NID_setct_CapTokenTBE: c_int = 574;
|
||||
pub const NID_setct_CapTokenTBEX: c_int = 575;
|
||||
pub const NID_setct_AcqCardCodeMsgTBE: c_int = 576;
|
||||
pub const NID_setct_AuthRevReqTBE: c_int = 577;
|
||||
pub const NID_setct_AuthRevResTBE: c_int = 578;
|
||||
pub const NID_setct_AuthRevResTBEB: c_int = 579;
|
||||
pub const NID_setct_CapReqTBE: c_int = 580;
|
||||
pub const NID_setct_CapReqTBEX: c_int = 581;
|
||||
pub const NID_setct_CapResTBE: c_int = 582;
|
||||
pub const NID_setct_CapRevReqTBE: c_int = 583;
|
||||
pub const NID_setct_CapRevReqTBEX: c_int = 584;
|
||||
pub const NID_setct_CapRevResTBE: c_int = 585;
|
||||
pub const NID_setct_CredReqTBE: c_int = 586;
|
||||
pub const NID_setct_CredReqTBEX: c_int = 587;
|
||||
pub const NID_setct_CredResTBE: c_int = 588;
|
||||
pub const NID_setct_CredRevReqTBE: c_int = 589;
|
||||
pub const NID_setct_CredRevReqTBEX: c_int = 590;
|
||||
pub const NID_setct_CredRevResTBE: c_int = 591;
|
||||
pub const NID_setct_BatchAdminReqTBE: c_int = 592;
|
||||
pub const NID_setct_BatchAdminResTBE: c_int = 593;
|
||||
pub const NID_setct_RegFormReqTBE: c_int = 594;
|
||||
pub const NID_setct_CertReqTBE: c_int = 595;
|
||||
pub const NID_setct_CertReqTBEX: c_int = 596;
|
||||
pub const NID_setct_CertResTBE: c_int = 597;
|
||||
pub const NID_setct_CRLNotificationTBS: c_int = 598;
|
||||
pub const NID_setct_CRLNotificationResTBS: c_int = 599;
|
||||
pub const NID_setct_BCIDistributionTBS: c_int = 600;
|
||||
pub const NID_setext_genCrypt: c_int = 601;
|
||||
pub const NID_setext_miAuth: c_int = 602;
|
||||
pub const NID_setext_pinSecure: c_int = 603;
|
||||
pub const NID_setext_pinAny: c_int = 604;
|
||||
pub const NID_setext_track2: c_int = 605;
|
||||
pub const NID_setext_cv: c_int = 606;
|
||||
pub const NID_set_policy_root: c_int = 607;
|
||||
pub const NID_setCext_hashedRoot: c_int = 608;
|
||||
pub const NID_setCext_certType: c_int = 609;
|
||||
pub const NID_setCext_merchData: c_int = 610;
|
||||
pub const NID_setCext_cCertRequired: c_int = 611;
|
||||
pub const NID_setCext_tunneling: c_int = 612;
|
||||
pub const NID_setCext_setExt: c_int = 613;
|
||||
pub const NID_setCext_setQualf: c_int = 614;
|
||||
pub const NID_setCext_PGWYcapabilities: c_int = 615;
|
||||
pub const NID_setCext_TokenIdentifier: c_int = 616;
|
||||
pub const NID_setCext_Track2Data: c_int = 617;
|
||||
pub const NID_setCext_TokenType: c_int = 618;
|
||||
pub const NID_setCext_IssuerCapabilities: c_int = 619;
|
||||
pub const NID_setAttr_Cert: c_int = 620;
|
||||
pub const NID_setAttr_PGWYcap: c_int = 621;
|
||||
pub const NID_setAttr_TokenType: c_int = 622;
|
||||
pub const NID_setAttr_IssCap: c_int = 623;
|
||||
pub const NID_set_rootKeyThumb: c_int = 624;
|
||||
pub const NID_set_addPolicy: c_int = 625;
|
||||
pub const NID_setAttr_Token_EMV: c_int = 626;
|
||||
pub const NID_setAttr_Token_B0Prime: c_int = 627;
|
||||
pub const NID_setAttr_IssCap_CVM: c_int = 628;
|
||||
pub const NID_setAttr_IssCap_T2: c_int = 629;
|
||||
pub const NID_setAttr_IssCap_Sig: c_int = 630;
|
||||
pub const NID_setAttr_GenCryptgrm: c_int = 631;
|
||||
pub const NID_setAttr_T2Enc: c_int = 632;
|
||||
pub const NID_setAttr_T2cleartxt: c_int = 633;
|
||||
pub const NID_setAttr_TokICCsig: c_int = 634;
|
||||
pub const NID_setAttr_SecDevSig: c_int = 635;
|
||||
pub const NID_set_brand_IATA_ATA: c_int = 636;
|
||||
pub const NID_set_brand_Diners: c_int = 637;
|
||||
pub const NID_set_brand_AmericanExpress: c_int = 638;
|
||||
pub const NID_set_brand_JCB: c_int = 639;
|
||||
pub const NID_set_brand_Visa: c_int = 640;
|
||||
pub const NID_set_brand_MasterCard: c_int = 641;
|
||||
pub const NID_set_brand_Novus: c_int = 642;
|
||||
pub const NID_des_cdmf: c_int = 643;
|
||||
pub const NID_rsaOAEPEncryptionSET: c_int = 644;
|
||||
pub const NID_ipsec3: c_int = 749;
|
||||
pub const NID_ipsec4: c_int = 750;
|
||||
pub const NID_whirlpool: c_int = 804;
|
||||
pub const NID_cryptopro: c_int = 805;
|
||||
pub const NID_cryptocom: c_int = 806;
|
||||
pub const NID_id_GostR3411_94_with_GostR3410_2001: c_int = 807;
|
||||
pub const NID_id_GostR3411_94_with_GostR3410_94: c_int = 808;
|
||||
pub const NID_id_GostR3411_94: c_int = 809;
|
||||
pub const NID_id_HMACGostR3411_94: c_int = 810;
|
||||
pub const NID_id_GostR3410_2001: c_int = 811;
|
||||
pub const NID_id_GostR3410_94: c_int = 812;
|
||||
pub const NID_id_Gost28147_89: c_int = 813;
|
||||
pub const NID_gost89_cnt: c_int = 814;
|
||||
pub const NID_id_Gost28147_89_MAC: c_int = 815;
|
||||
pub const NID_id_GostR3411_94_prf: c_int = 816;
|
||||
pub const NID_id_GostR3410_2001DH: c_int = 817;
|
||||
pub const NID_id_GostR3410_94DH: c_int = 818;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_KeyMeshing: c_int = 819;
|
||||
pub const NID_id_Gost28147_89_None_KeyMeshing: c_int = 820;
|
||||
pub const NID_id_GostR3411_94_TestParamSet: c_int = 821;
|
||||
pub const NID_id_GostR3411_94_CryptoProParamSet: c_int = 822;
|
||||
pub const NID_id_Gost28147_89_TestParamSet: c_int = 823;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_A_ParamSet: c_int = 824;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_B_ParamSet: c_int = 825;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_C_ParamSet: c_int = 826;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_D_ParamSet: c_int = 827;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet: c_int = 828;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet: c_int = 829;
|
||||
pub const NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet: c_int = 830;
|
||||
pub const NID_id_GostR3410_94_TestParamSet: c_int = 831;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_A_ParamSet: c_int = 832;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_B_ParamSet: c_int = 833;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_C_ParamSet: c_int = 834;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_D_ParamSet: c_int = 835;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_XchA_ParamSet: c_int = 836;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_XchB_ParamSet: c_int = 837;
|
||||
pub const NID_id_GostR3410_94_CryptoPro_XchC_ParamSet: c_int = 838;
|
||||
pub const NID_id_GostR3410_2001_TestParamSet: c_int = 839;
|
||||
pub const NID_id_GostR3410_2001_CryptoPro_A_ParamSet: c_int = 840;
|
||||
pub const NID_id_GostR3410_2001_CryptoPro_B_ParamSet: c_int = 841;
|
||||
pub const NID_id_GostR3410_2001_CryptoPro_C_ParamSet: c_int = 842;
|
||||
pub const NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: c_int = 843;
|
||||
pub const NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: c_int = 844;
|
||||
pub const NID_id_GostR3410_94_a: c_int = 845;
|
||||
pub const NID_id_GostR3410_94_aBis: c_int = 846;
|
||||
pub const NID_id_GostR3410_94_b: c_int = 847;
|
||||
pub const NID_id_GostR3410_94_bBis: c_int = 848;
|
||||
pub const NID_id_Gost28147_89_cc: c_int = 849;
|
||||
pub const NID_id_GostR3410_94_cc: c_int = 850;
|
||||
pub const NID_id_GostR3410_2001_cc: c_int = 851;
|
||||
pub const NID_id_GostR3411_94_with_GostR3410_94_cc: c_int = 852;
|
||||
pub const NID_id_GostR3411_94_with_GostR3410_2001_cc: c_int = 853;
|
||||
pub const NID_id_GostR3410_2001_ParamSet_cc: c_int = 854;
|
||||
pub const NID_camellia_128_cbc: c_int = 751;
|
||||
pub const NID_camellia_192_cbc: c_int = 752;
|
||||
pub const NID_camellia_256_cbc: c_int = 753;
|
||||
pub const NID_id_camellia128_wrap: c_int = 907;
|
||||
pub const NID_id_camellia192_wrap: c_int = 908;
|
||||
pub const NID_id_camellia256_wrap: c_int = 909;
|
||||
pub const NID_camellia_128_ecb: c_int = 754;
|
||||
pub const NID_camellia_128_ofb128: c_int = 766;
|
||||
pub const NID_camellia_128_cfb128: c_int = 757;
|
||||
pub const NID_camellia_192_ecb: c_int = 755;
|
||||
pub const NID_camellia_192_ofb128: c_int = 767;
|
||||
pub const NID_camellia_192_cfb128: c_int = 758;
|
||||
pub const NID_camellia_256_ecb: c_int = 756;
|
||||
pub const NID_camellia_256_ofb128: c_int = 768;
|
||||
pub const NID_camellia_256_cfb128: c_int = 759;
|
||||
pub const NID_camellia_128_cfb1: c_int = 760;
|
||||
pub const NID_camellia_192_cfb1: c_int = 761;
|
||||
pub const NID_camellia_256_cfb1: c_int = 762;
|
||||
pub const NID_camellia_128_cfb8: c_int = 763;
|
||||
pub const NID_camellia_192_cfb8: c_int = 764;
|
||||
pub const NID_camellia_256_cfb8: c_int = 765;
|
||||
pub const NID_kisa: c_int = 773;
|
||||
pub const NID_seed_ecb: c_int = 776;
|
||||
pub const NID_seed_cbc: c_int = 777;
|
||||
pub const NID_seed_cfb128: c_int = 779;
|
||||
pub const NID_seed_ofb128: c_int = 778;
|
||||
pub const NID_hmac: c_int = 855;
|
||||
pub const NID_cmac: c_int = 894;
|
||||
pub const NID_rc4_hmac_md5: c_int = 915;
|
||||
pub const NID_aes_128_cbc_hmac_sha1: c_int = 916;
|
||||
pub const NID_aes_192_cbc_hmac_sha1: c_int = 917;
|
||||
pub const NID_aes_256_cbc_hmac_sha1: c_int = 918;
|
||||
#[cfg(ossl111)]
|
||||
pub const NID_ED25519: c_int = 1087;
|
||||
#[cfg(ossl111)]
|
||||
pub const NID_ED448: c_int = 1088;
|
||||
18
openssl-sys/src/object.rs
Normal file
18
openssl-sys/src/object.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
extern "C" {
|
||||
pub fn OBJ_nid2ln(nid: c_int) -> *const c_char;
|
||||
pub fn OBJ_nid2sn(nid: c_int) -> *const c_char;
|
||||
pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int;
|
||||
pub fn OBJ_obj2txt(
|
||||
buf: *mut c_char,
|
||||
buf_len: c_int,
|
||||
a: *const ASN1_OBJECT,
|
||||
no_name: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn OBJ_find_sigid_algs(signid: c_int, pdig_nid: *mut c_int, ppkey_nid: *mut c_int)
|
||||
-> c_int;
|
||||
}
|
||||
118
openssl-sys/src/ocsp.rs
Normal file
118
openssl-sys/src/ocsp.rs
Normal file
@ -0,0 +1,118 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub const OCSP_REVOKED_STATUS_NOSTATUS: c_int = -1;
|
||||
pub const OCSP_REVOKED_STATUS_UNSPECIFIED: c_int = 0;
|
||||
pub const OCSP_REVOKED_STATUS_KEYCOMPROMISE: c_int = 1;
|
||||
pub const OCSP_REVOKED_STATUS_CACOMPROMISE: c_int = 2;
|
||||
pub const OCSP_REVOKED_STATUS_AFFILIATIONCHANGED: c_int = 3;
|
||||
pub const OCSP_REVOKED_STATUS_SUPERSEDED: c_int = 4;
|
||||
pub const OCSP_REVOKED_STATUS_CESSATIONOFOPERATION: c_int = 5;
|
||||
pub const OCSP_REVOKED_STATUS_CERTIFICATEHOLD: c_int = 6;
|
||||
pub const OCSP_REVOKED_STATUS_REMOVEFROMCRL: c_int = 8;
|
||||
|
||||
pub const OCSP_NOCERTS: c_ulong = 0x1;
|
||||
pub const OCSP_NOINTERN: c_ulong = 0x2;
|
||||
pub const OCSP_NOSIGS: c_ulong = 0x4;
|
||||
pub const OCSP_NOCHAIN: c_ulong = 0x8;
|
||||
pub const OCSP_NOVERIFY: c_ulong = 0x10;
|
||||
pub const OCSP_NOEXPLICIT: c_ulong = 0x20;
|
||||
pub const OCSP_NOCASIGN: c_ulong = 0x40;
|
||||
pub const OCSP_NODELEGATED: c_ulong = 0x80;
|
||||
pub const OCSP_NOCHECKS: c_ulong = 0x100;
|
||||
pub const OCSP_TRUSTOTHER: c_ulong = 0x200;
|
||||
pub const OCSP_RESPID_KEY: c_ulong = 0x400;
|
||||
pub const OCSP_NOTIME: c_ulong = 0x800;
|
||||
|
||||
pub enum OCSP_CERTID {}
|
||||
|
||||
pub enum OCSP_ONEREQ {}
|
||||
|
||||
pub enum OCSP_REQUEST {}
|
||||
|
||||
pub const OCSP_RESPONSE_STATUS_SUCCESSFUL: c_int = 0;
|
||||
pub const OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: c_int = 1;
|
||||
pub const OCSP_RESPONSE_STATUS_INTERNALERROR: c_int = 2;
|
||||
pub const OCSP_RESPONSE_STATUS_TRYLATER: c_int = 3;
|
||||
pub const OCSP_RESPONSE_STATUS_SIGREQUIRED: c_int = 5;
|
||||
pub const OCSP_RESPONSE_STATUS_UNAUTHORIZED: c_int = 6;
|
||||
|
||||
pub const V_OCSP_CERTSTATUS_GOOD: c_int = 0;
|
||||
pub const V_OCSP_CERTSTATUS_REVOKED: c_int = 1;
|
||||
pub const V_OCSP_CERTSTATUS_UNKNOWN: c_int = 2;
|
||||
|
||||
pub enum OCSP_BASICRESP {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl281))] {
|
||||
extern "C" {
|
||||
pub fn OCSP_cert_to_id(
|
||||
dgst: *const EVP_MD,
|
||||
subject: *const X509,
|
||||
issuer: *const X509,
|
||||
) -> *mut OCSP_CERTID;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn OCSP_cert_to_id(
|
||||
dgst: *const EVP_MD,
|
||||
subject: *mut X509,
|
||||
issuer: *mut X509,
|
||||
) -> *mut ::OCSP_CERTID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn OCSP_request_add0_id(r: *mut OCSP_REQUEST, id: *mut OCSP_CERTID) -> *mut OCSP_ONEREQ;
|
||||
|
||||
pub fn OCSP_resp_find_status(
|
||||
bs: *mut OCSP_BASICRESP,
|
||||
id: *mut OCSP_CERTID,
|
||||
status: *mut c_int,
|
||||
reason: *mut c_int,
|
||||
revtime: *mut *mut ASN1_GENERALIZEDTIME,
|
||||
thisupd: *mut *mut ASN1_GENERALIZEDTIME,
|
||||
nextupd: *mut *mut ASN1_GENERALIZEDTIME,
|
||||
) -> c_int;
|
||||
pub fn OCSP_check_validity(
|
||||
thisupd: *mut ASN1_GENERALIZEDTIME,
|
||||
nextupd: *mut ASN1_GENERALIZEDTIME,
|
||||
sec: c_long,
|
||||
maxsec: c_long,
|
||||
) -> c_int;
|
||||
|
||||
pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> c_int;
|
||||
pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP;
|
||||
|
||||
pub fn OCSP_response_create(status: c_int, bs: *mut OCSP_BASICRESP) -> *mut OCSP_RESPONSE;
|
||||
|
||||
pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP;
|
||||
pub fn OCSP_BASICRESP_free(r: *mut OCSP_BASICRESP);
|
||||
pub fn OCSP_RESPONSE_new() -> *mut OCSP_RESPONSE;
|
||||
pub fn OCSP_RESPONSE_free(r: *mut OCSP_RESPONSE);
|
||||
pub fn i2d_OCSP_RESPONSE(a: *mut OCSP_RESPONSE, pp: *mut *mut c_uchar) -> c_int;
|
||||
pub fn d2i_OCSP_RESPONSE(
|
||||
a: *mut *mut OCSP_RESPONSE,
|
||||
pp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut OCSP_RESPONSE;
|
||||
pub fn OCSP_ONEREQ_free(r: *mut OCSP_ONEREQ);
|
||||
pub fn OCSP_CERTID_free(id: *mut OCSP_CERTID);
|
||||
pub fn OCSP_REQUEST_new() -> *mut OCSP_REQUEST;
|
||||
pub fn OCSP_REQUEST_free(r: *mut OCSP_REQUEST);
|
||||
pub fn i2d_OCSP_REQUEST(a: *mut OCSP_REQUEST, pp: *mut *mut c_uchar) -> c_int;
|
||||
pub fn d2i_OCSP_REQUEST(
|
||||
a: *mut *mut OCSP_REQUEST,
|
||||
pp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut OCSP_REQUEST;
|
||||
|
||||
pub fn OCSP_basic_verify(
|
||||
bs: *mut OCSP_BASICRESP,
|
||||
certs: *mut stack_st_X509,
|
||||
st: *mut X509_STORE,
|
||||
flags: c_ulong,
|
||||
) -> c_int;
|
||||
}
|
||||
@ -1,985 +0,0 @@
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::process;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong};
|
||||
#[cfg(not(ossl101))]
|
||||
use libc::time_t;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_ASN1_OBJECT {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509 {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_NAME {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_ATTRIBUTE {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_X509_EXTENSION {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_GENERAL_NAME {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_void {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_SSL_CIPHER {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_OPENSSL_STRING {
|
||||
pub stack: _STACK,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _STACK {
|
||||
pub num: c_int,
|
||||
pub data: *mut *mut c_char,
|
||||
pub sorted: c_int,
|
||||
pub num_alloc: c_int,
|
||||
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIO_METHOD {
|
||||
pub type_: c_int,
|
||||
pub name: *const c_char,
|
||||
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
|
||||
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
|
||||
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
|
||||
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
|
||||
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
|
||||
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub meth: *const ::RSA_METHOD,
|
||||
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub n: *mut ::BIGNUM,
|
||||
pub e: *mut ::BIGNUM,
|
||||
pub d: *mut ::BIGNUM,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub dmp1: *mut ::BIGNUM,
|
||||
pub dmq1: *mut ::BIGNUM,
|
||||
pub iqmp: *mut ::BIGNUM,
|
||||
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub references: c_int,
|
||||
pub flags: c_int,
|
||||
|
||||
pub _method_mod_n: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_p: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_q: *mut ::BN_MONT_CTX,
|
||||
|
||||
pub bignum_data: *mut c_char,
|
||||
pub blinding: *mut ::BN_BLINDING,
|
||||
pub mt_blinding: *mut ::BN_BLINDING,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub write_params: c_int,
|
||||
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub g: *mut ::BIGNUM,
|
||||
pub pub_key: *mut ::BIGNUM,
|
||||
pub priv_key: *mut ::BIGNUM,
|
||||
pub kinv: *mut ::BIGNUM,
|
||||
pub r: *mut ::BIGNUM,
|
||||
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut ::BN_MONT_CTX,
|
||||
pub references: c_int,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub meth: *const ::DSA_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_PKEY {
|
||||
pub type_: c_int,
|
||||
pub save_type: c_int,
|
||||
pub references: c_int,
|
||||
pub ameth: *const ::EVP_PKEY_ASN1_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub pkey: *mut c_void,
|
||||
pub save_parameters: c_int,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIO {
|
||||
pub method: *mut ::BIO_METHOD,
|
||||
pub callback: Option<
|
||||
unsafe extern "C" fn(*mut ::BIO,
|
||||
c_int,
|
||||
*const c_char,
|
||||
c_int,
|
||||
c_long,
|
||||
c_long)
|
||||
-> c_long,
|
||||
>,
|
||||
pub cb_arg: *mut c_char,
|
||||
pub init: c_int,
|
||||
pub shutdown: c_int,
|
||||
pub flags: c_int,
|
||||
pub retry_reason: c_int,
|
||||
pub num: c_int,
|
||||
pub ptr: *mut c_void,
|
||||
pub next_bio: *mut ::BIO,
|
||||
pub prev_bio: *mut ::BIO,
|
||||
pub references: c_int,
|
||||
pub num_read: c_ulong,
|
||||
pub num_write: c_ulong,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CRYPTO_EX_DATA {
|
||||
pub sk: *mut ::stack_st_void,
|
||||
pub dummy: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_MD_CTX {
|
||||
digest: *mut ::EVP_MD,
|
||||
engine: *mut ::ENGINE,
|
||||
flags: c_ulong,
|
||||
md_data: *mut c_void,
|
||||
pctx: *mut ::EVP_PKEY_CTX,
|
||||
update: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EVP_CIPHER {
|
||||
pub nid: c_int,
|
||||
pub block_size: c_int,
|
||||
pub key_len: c_int,
|
||||
pub iv_len: c_int,
|
||||
pub flags: c_ulong,
|
||||
pub init: Option<
|
||||
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
|
||||
*const c_uchar,
|
||||
*const c_uchar,
|
||||
c_int)
|
||||
-> c_int,
|
||||
>,
|
||||
pub do_cipher: Option<
|
||||
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
|
||||
*mut c_uchar,
|
||||
*const c_uchar,
|
||||
size_t)
|
||||
-> c_int,
|
||||
>,
|
||||
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
|
||||
pub ctx_size: c_int,
|
||||
pub set_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
|
||||
pub get_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
|
||||
pub ctrl:
|
||||
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
|
||||
pub app_data: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct HMAC_CTX {
|
||||
md: *mut ::EVP_MD,
|
||||
md_ctx: ::EVP_MD_CTX,
|
||||
i_ctx: ::EVP_MD_CTX,
|
||||
o_ctx: ::EVP_MD_CTX,
|
||||
key_length: c_uint,
|
||||
key: [c_uchar; 128],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BIGNUM {
|
||||
pub d: *mut ::BN_ULONG,
|
||||
pub top: c_int,
|
||||
pub dmax: c_int,
|
||||
pub neg: c_int,
|
||||
pub flags: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DH {
|
||||
pub pad: c_int,
|
||||
pub version: c_int,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub g: *mut ::BIGNUM,
|
||||
pub length: c_long,
|
||||
pub pub_key: *mut ::BIGNUM,
|
||||
pub priv_key: *mut ::BIGNUM,
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut ::BN_MONT_CTX,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub j: *mut ::BIGNUM,
|
||||
pub seed: *mut c_uchar,
|
||||
pub seedlen: c_int,
|
||||
pub counter: *mut ::BIGNUM,
|
||||
pub references: c_int,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub meth: *const ::DH_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509 {
|
||||
pub cert_info: *mut X509_CINF,
|
||||
pub sig_alg: *mut ::X509_ALGOR,
|
||||
pub signature: *mut ::ASN1_BIT_STRING,
|
||||
pub valid: c_int,
|
||||
pub references: c_int,
|
||||
pub name: *mut c_char,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub ex_pathlen: c_long,
|
||||
pub ex_pcpathlen: c_long,
|
||||
pub ex_flags: c_ulong,
|
||||
pub ex_kusage: c_ulong,
|
||||
pub ex_xkusage: c_ulong,
|
||||
pub ex_nscert: c_ulong,
|
||||
skid: *mut c_void,
|
||||
akid: *mut c_void,
|
||||
policy_cache: *mut c_void,
|
||||
crldp: *mut c_void,
|
||||
altname: *mut c_void,
|
||||
nc: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
|
||||
rfc3779_addr: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
|
||||
rfc3779_asid: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
|
||||
sha1_hash: [c_uchar; 20],
|
||||
aux: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_CINF {
|
||||
version: *mut c_void,
|
||||
serialNumber: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
issuer: *mut c_void,
|
||||
pub validity: *mut X509_VAL,
|
||||
subject: *mut c_void,
|
||||
key: *mut c_void,
|
||||
issuerUID: *mut c_void,
|
||||
subjectUID: *mut c_void,
|
||||
pub extensions: *mut stack_st_X509_EXTENSION,
|
||||
enc: ASN1_ENCODING,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_ALGOR {
|
||||
pub algorithm: *mut ::ASN1_OBJECT,
|
||||
parameter: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ASN1_ENCODING {
|
||||
pub enc: *mut c_uchar,
|
||||
pub len: c_long,
|
||||
pub modified: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VAL {
|
||||
pub notBefore: *mut ::ASN1_TIME,
|
||||
pub notAfter: *mut ::ASN1_TIME,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ_INFO {
|
||||
pub enc: ASN1_ENCODING,
|
||||
pub version: *mut ::ASN1_INTEGER,
|
||||
pub subject: *mut ::X509_NAME,
|
||||
pubkey: *mut c_void,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ {
|
||||
pub req_info: *mut X509_REQ_INFO,
|
||||
sig_alg: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
references: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
type_: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut c_void,
|
||||
wbio: *mut c_void,
|
||||
bbio: *mut c_void,
|
||||
rwstate: c_int,
|
||||
in_handshake: c_int,
|
||||
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
|
||||
pub server: c_int,
|
||||
new_session: c_int,
|
||||
quiet_session: c_int,
|
||||
shutdown: c_int,
|
||||
state: c_int,
|
||||
rstate: c_int,
|
||||
init_buf: *mut c_void,
|
||||
init_msg: *mut c_void,
|
||||
init_num: c_int,
|
||||
init_off: c_int,
|
||||
packet: *mut c_uchar,
|
||||
packet_length: c_uint,
|
||||
s2: *mut c_void,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: Option<
|
||||
unsafe extern "C" fn(c_int,
|
||||
c_int,
|
||||
c_int,
|
||||
*const c_void,
|
||||
size_t,
|
||||
*mut SSL,
|
||||
*mut c_void),
|
||||
>,
|
||||
msg_callback_arg: *mut c_void,
|
||||
hit: c_int,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
|
||||
mac_flags: c_int,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut ::EVP_MD_CTX,
|
||||
expand: *mut c_void,
|
||||
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
write_hash: *mut ::EVP_MD_CTX,
|
||||
compress: *mut c_void,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
generate_session_id: ::GEN_SESSION_CB,
|
||||
verify_mode: c_int,
|
||||
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
|
||||
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
kssl_ctx: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_client_callback: Option<
|
||||
unsafe extern "C" fn(*mut SSL,
|
||||
*const c_char,
|
||||
*mut c_char,
|
||||
c_uint,
|
||||
*mut c_uchar,
|
||||
c_uint)
|
||||
-> c_uint,
|
||||
>,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_server_callback:
|
||||
Option<unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint>,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
debug: c_int,
|
||||
verify_result: c_long,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
client_CA: *mut stack_st_X509_NAME,
|
||||
references: c_int,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
first_packet: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_debug_cb:
|
||||
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_debug_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hostname: *mut c_char,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
servername_done: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_type: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_expected: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_ids: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_exts: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_resp: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_resplen: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticket_expected: c_int,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_len: size_t,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_session_ticket: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_ticket_ext_cb_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_secret_cb: ::tls_session_secret_cb_fn,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_secret_cb_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_proto_negotiated: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_proto_negotiated_len: c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
srtp_profiles: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
srtp_profile: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_heartbeat: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hb_pending: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hb_seq: c_uint,
|
||||
renegotiate: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_ctx: ::SRP_CTX,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *mut c_void,
|
||||
cipher_list: *mut c_void,
|
||||
cipher_list_by_id: *mut c_void,
|
||||
cert_store: *mut c_void,
|
||||
sessions: *mut c_void,
|
||||
session_cache_size: c_ulong,
|
||||
session_cache_head: *mut c_void,
|
||||
session_cache_tail: *mut c_void,
|
||||
session_cache_mode: c_int,
|
||||
session_timeout: c_long,
|
||||
new_session_cb: *mut c_void,
|
||||
remove_session_cb: *mut c_void,
|
||||
get_session_cb: *mut c_void,
|
||||
stats: [c_int; 11],
|
||||
pub references: c_int,
|
||||
app_verify_callback: *mut c_void,
|
||||
app_verify_arg: *mut c_void,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
client_cert_cb: *mut c_void,
|
||||
app_gen_cookie_cb: *mut c_void,
|
||||
app_verify_cookie_cb: *mut c_void,
|
||||
ex_dat: ::CRYPTO_EX_DATA,
|
||||
rsa_md5: *mut c_void,
|
||||
md5: *mut c_void,
|
||||
sha1: *mut c_void,
|
||||
extra_certs: *mut c_void,
|
||||
comp_methods: *mut c_void,
|
||||
info_callback: *mut c_void,
|
||||
client_CA: *mut c_void,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
cert: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: *mut c_void,
|
||||
msg_callback_arg: *mut c_void,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; 32],
|
||||
default_verify_callback: *mut c_void,
|
||||
generate_session_id: *mut c_void,
|
||||
param: *mut c_void,
|
||||
quiet_shutdown: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
|
||||
client_cert_engine: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_servername_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsect_servername_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_key_name: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_hmac_key: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_aes_key: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticket_key_cb: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_cb: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_callback_arg: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity_hint: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_client_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_server_callback: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
freelist_max_len: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
wbuf_freelist: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
rbuf_freelist: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_ctx: SRP_CTX,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_protos_advertised_cb: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_protos_advertised_cb_arg: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_proto_select_cb: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
|
||||
next_proto_select_cb_arg: *mut c_void,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
|
||||
srtp_profiles: *mut c_void,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
srtp_profiles: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_select_cb: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_select_cb_arg: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_SESSION {
|
||||
ssl_version: c_int,
|
||||
key_arg_length: c_uint,
|
||||
key_arg: [c_uchar; SSL_MAX_KEY_ARG_LENGTH as usize],
|
||||
pub master_key_length: c_int,
|
||||
pub master_key: [c_uchar; 48],
|
||||
session_id_length: c_uint,
|
||||
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
krb5_client_princ_len: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
krb5_client_princ: [c_uchar; SSL_MAX_KRB5_PRINCIPAL_LENGTH as usize],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity_hint: *mut c_char,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity: *mut c_char,
|
||||
not_resumable: c_int,
|
||||
sess_cert: *mut c_void,
|
||||
peer: *mut X509,
|
||||
verify_result: c_long,
|
||||
pub references: c_int,
|
||||
timeout: c_long,
|
||||
time: c_long,
|
||||
compress_meth: c_uint,
|
||||
cipher: *const c_void,
|
||||
cipher_id: c_ulong,
|
||||
ciphers: *mut c_void,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
prev: *mut c_void,
|
||||
next: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hostname: *mut c_char,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticklen: size_t,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_lifetime_hint: c_long,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_username: *mut c_char,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SRP_CTX {
|
||||
SRP_cb_arg: *mut c_void,
|
||||
TLS_ext_srp_username_callback: *mut c_void,
|
||||
SRP_verify_param_callback: *mut c_void,
|
||||
SRP_give_srp_client_pwd_callback: *mut c_void,
|
||||
login: *mut c_void,
|
||||
N: *mut c_void,
|
||||
g: *mut c_void,
|
||||
s: *mut c_void,
|
||||
B: *mut c_void,
|
||||
A: *mut c_void,
|
||||
a: *mut c_void,
|
||||
b: *mut c_void,
|
||||
v: *mut c_void,
|
||||
info: *mut c_void,
|
||||
stringth: c_int,
|
||||
srp_Mask: c_ulong,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(not(ossl101))]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
pub id: *mut X509_VERIFY_PARAM_ID,
|
||||
}
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
pub enum X509_VERIFY_PARAM_ID {}
|
||||
pub enum PKCS12 {}
|
||||
|
||||
pub const SSL_CTRL_GET_SESSION_REUSED: c_int = 8;
|
||||
pub const SSL_CTRL_OPTIONS: c_int = 32;
|
||||
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
||||
#[cfg(ossl102)]
|
||||
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
|
||||
|
||||
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000001;
|
||||
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x00000002;
|
||||
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x00000008;
|
||||
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x00000020;
|
||||
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x00000080;
|
||||
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x00000100;
|
||||
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x00000200;
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
|
||||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x01000000;
|
||||
|
||||
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_KEY_ARG_LENGTH: c_int = 8;
|
||||
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
|
||||
pub const SSL_MAX_KRB5_PRINCIPAL_LENGTH: c_int = 256;
|
||||
|
||||
pub const SSLEAY_VERSION: c_int = 0;
|
||||
pub const SSLEAY_CFLAGS: c_int = 2;
|
||||
pub const SSLEAY_BUILT_ON: c_int = 3;
|
||||
pub const SSLEAY_PLATFORM: c_int = 4;
|
||||
pub const SSLEAY_DIR: c_int = 5;
|
||||
|
||||
pub const CRYPTO_LOCK_X509: c_int = 3;
|
||||
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
|
||||
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
|
||||
|
||||
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
|
||||
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
|
||||
*mut Vec<Option<MutexGuard<'static, ()>>>;
|
||||
|
||||
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
|
||||
let mutex = &(*MUTEXES)[n as usize];
|
||||
|
||||
if mode & ::CRYPTO_LOCK != 0 {
|
||||
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
|
||||
} else {
|
||||
if let None = (*GUARDS)[n as usize].take() {
|
||||
let _ = writeln!(
|
||||
io::stderr(),
|
||||
"BUG: rust-openssl lock {} already unlocked, aborting",
|
||||
n
|
||||
);
|
||||
process::abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
static INIT: Once = ONCE_INIT;
|
||||
|
||||
INIT.call_once(|| unsafe {
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
OPENSSL_add_all_algorithms_noconf();
|
||||
|
||||
let num_locks = ::CRYPTO_num_locks();
|
||||
let mut mutexes = Box::new(Vec::new());
|
||||
for _ in 0..num_locks {
|
||||
mutexes.push(Mutex::new(()));
|
||||
}
|
||||
MUTEXES = mem::transmute(mutexes);
|
||||
let guards: Box<Vec<Option<MutexGuard<()>>>> =
|
||||
Box::new((0..num_locks).map(|_| None).collect());
|
||||
GUARDS = mem::transmute(guards);
|
||||
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
set_id_callback();
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn set_id_callback() {
|
||||
unsafe extern "C" fn thread_id() -> c_ulong {
|
||||
::libc::pthread_self() as c_ulong
|
||||
}
|
||||
|
||||
unsafe {
|
||||
CRYPTO_set_id_callback(thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn set_id_callback() {}
|
||||
|
||||
// macros
|
||||
|
||||
#[cfg(ossl102)]
|
||||
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx,
|
||||
SSL_CTRL_SET_ECDH_AUTO,
|
||||
onoff as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_int
|
||||
}
|
||||
|
||||
#[cfg(ossl102)]
|
||||
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
|
||||
::SSL_ctrl(
|
||||
ssl,
|
||||
SSL_CTRL_SET_ECDH_AUTO,
|
||||
onoff as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_int
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
|
||||
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
|
||||
pub fn BIO_s_file() -> *mut BIO_METHOD;
|
||||
pub fn BIO_s_mem() -> *mut BIO_METHOD;
|
||||
|
||||
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
|
||||
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
|
||||
pub fn CRYPTO_free(buf: *mut c_void);
|
||||
pub fn CRYPTO_num_locks() -> c_int;
|
||||
pub fn CRYPTO_set_locking_callback(
|
||||
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
|
||||
);
|
||||
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
|
||||
|
||||
pub fn ERR_load_crypto_strings();
|
||||
|
||||
pub fn RSA_generate_key(
|
||||
modsz: c_int,
|
||||
e: c_ulong,
|
||||
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
|
||||
cbarg: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
|
||||
pub fn OCSP_cert_to_id(
|
||||
dgst: *const ::EVP_MD,
|
||||
subject: *mut ::X509,
|
||||
issuer: *mut ::X509,
|
||||
) -> *mut ::OCSP_CERTID;
|
||||
|
||||
pub fn PKCS12_create(
|
||||
pass: *mut c_char,
|
||||
friendly_name: *mut c_char,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
ca: *mut stack_st_X509,
|
||||
nid_key: c_int,
|
||||
nid_cert: c_int,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
keytype: c_int,
|
||||
) -> *mut PKCS12;
|
||||
|
||||
pub fn SSL_library_init() -> c_int;
|
||||
pub fn SSL_load_error_strings();
|
||||
pub fn OPENSSL_add_all_algorithms_noconf();
|
||||
pub fn HMAC_CTX_init(ctx: *mut ::HMAC_CTX);
|
||||
pub fn HMAC_CTX_cleanup(ctx: *mut ::HMAC_CTX);
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SSL3_METHOD"))]
|
||||
pub fn SSLv3_method() -> *const ::SSL_METHOD;
|
||||
pub fn TLSv1_method() -> *const ::SSL_METHOD;
|
||||
pub fn SSLv23_method() -> *const ::SSL_METHOD;
|
||||
pub fn TLSv1_1_method() -> *const ::SSL_METHOD;
|
||||
pub fn TLSv1_2_method() -> *const ::SSL_METHOD;
|
||||
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
|
||||
#[cfg(ossl102)]
|
||||
pub fn DTLSv1_2_method() -> *const ::SSL_METHOD;
|
||||
pub fn SSL_get_ex_new_index(
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<::CRYPTO_EX_new>,
|
||||
dup_func: Option<::CRYPTO_EX_dup>,
|
||||
free_func: Option<::CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
pub fn SSL_set_tmp_ecdh_callback(
|
||||
ssl: *mut ::SSL,
|
||||
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
|
||||
-> *mut ::EC_KEY,
|
||||
);
|
||||
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
|
||||
pub fn SSL_CTX_get_ex_new_index(
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<::CRYPTO_EX_new>,
|
||||
dup_func: Option<::CRYPTO_EX_dup>,
|
||||
free_func: Option<::CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
pub fn SSL_CTX_set_tmp_ecdh_callback(
|
||||
ctx: *mut ::SSL_CTX,
|
||||
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
|
||||
-> *mut ::EC_KEY,
|
||||
);
|
||||
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_get_ext_d2i(
|
||||
x: *mut ::X509,
|
||||
nid: c_int,
|
||||
crit: *mut c_int,
|
||||
idx: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
pub fn X509_NAME_add_entry_by_NID(
|
||||
x: *mut ::X509_NAME,
|
||||
field: c_int,
|
||||
ty: c_int,
|
||||
bytes: *mut c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
#[cfg(not(ossl101))]
|
||||
pub fn X509_get0_signature(
|
||||
psig: *mut *mut ::ASN1_BIT_STRING,
|
||||
palg: *mut *mut ::X509_ALGOR,
|
||||
x: *const ::X509,
|
||||
);
|
||||
#[cfg(not(ossl101))]
|
||||
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
|
||||
#[cfg(not(ossl101))]
|
||||
pub fn X509_ALGOR_get0(
|
||||
paobj: *mut *mut ::ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
ppval: *mut *mut c_void,
|
||||
alg: *mut ::X509_ALGOR,
|
||||
);
|
||||
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
|
||||
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
|
||||
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
pub fn X509V3_EXT_nconf_nid(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
ext_nid: c_int,
|
||||
value: *mut c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn X509V3_EXT_nconf(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
name: *mut c_char,
|
||||
value: *mut c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
|
||||
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
|
||||
pub fn CRYPTO_add_lock(
|
||||
pointer: *mut c_int,
|
||||
amount: c_int,
|
||||
type_: c_int,
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
) -> c_int;
|
||||
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
|
||||
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
|
||||
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn sk_new_null() -> *mut _STACK;
|
||||
pub fn sk_num(st: *const _STACK) -> c_int;
|
||||
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
|
||||
pub fn sk_free(st: *mut _STACK);
|
||||
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
|
||||
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
|
||||
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
|
||||
|
||||
pub fn SSLeay() -> c_ulong;
|
||||
pub fn SSLeay_version(key: c_int) -> *const c_char;
|
||||
}
|
||||
@ -1,291 +0,0 @@
|
||||
use libc::{c_int, c_void, c_char, c_uchar, c_ulong, c_long, c_uint, size_t};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::ptr;
|
||||
|
||||
pub enum BIGNUM {}
|
||||
pub enum BIO {}
|
||||
pub enum BIO_METHOD {}
|
||||
pub enum CRYPTO_EX_DATA {}
|
||||
pub enum DH {}
|
||||
pub enum DSA {}
|
||||
pub enum EVP_CIPHER {}
|
||||
pub enum EVP_MD_CTX {}
|
||||
pub enum EVP_PKEY {}
|
||||
pub enum HMAC_CTX {}
|
||||
pub enum OPENSSL_STACK {}
|
||||
pub enum PKCS12 {}
|
||||
pub enum RSA {}
|
||||
pub enum SSL {}
|
||||
pub enum SSL_CTX {}
|
||||
pub enum SSL_SESSION {}
|
||||
pub enum stack_st_ASN1_OBJECT {}
|
||||
pub enum stack_st_GENERAL_NAME {}
|
||||
pub enum stack_st_OPENSSL_STRING {}
|
||||
pub enum stack_st_void {}
|
||||
pub enum stack_st_X509 {}
|
||||
pub enum stack_st_X509_NAME {}
|
||||
pub enum stack_st_X509_ATTRIBUTE {}
|
||||
pub enum stack_st_X509_EXTENSION {}
|
||||
pub enum stack_st_SSL_CIPHER {}
|
||||
pub enum OPENSSL_INIT_SETTINGS {}
|
||||
pub enum X509 {}
|
||||
pub enum X509_ALGOR {}
|
||||
pub enum X509_VERIFY_PARAM {}
|
||||
pub enum X509_REQ {}
|
||||
|
||||
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00000000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x00000000;
|
||||
|
||||
pub const OPENSSL_VERSION: c_int = 0;
|
||||
pub const OPENSSL_CFLAGS: c_int = 1;
|
||||
pub const OPENSSL_BUILT_ON: c_int = 2;
|
||||
pub const OPENSSL_PLATFORM: c_int = 3;
|
||||
pub const OPENSSL_DIR: c_int = 4;
|
||||
|
||||
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
|
||||
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
|
||||
|
||||
pub const OPENSSL_INIT_LOAD_SSL_STRINGS: u64 = 0x00200000;
|
||||
|
||||
pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;
|
||||
|
||||
pub fn init() {
|
||||
// explicitly initialize to work around https://github.com/openssl/openssl/issues/3505
|
||||
static INIT: Once = ONCE_INIT;
|
||||
|
||||
INIT.call_once(|| unsafe {
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, ptr::null_mut());
|
||||
})
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
|
||||
pub fn BIO_s_file() -> *const BIO_METHOD;
|
||||
pub fn BIO_s_mem() -> *const BIO_METHOD;
|
||||
|
||||
pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
|
||||
|
||||
pub fn CRYPTO_malloc(num: size_t, file: *const c_char, line: c_int) -> *mut c_void;
|
||||
pub fn CRYPTO_free(buf: *mut c_void, file: *const c_char, line: c_int);
|
||||
|
||||
pub fn EVP_chacha20() -> *const ::EVP_CIPHER;
|
||||
pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER;
|
||||
|
||||
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
|
||||
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
|
||||
|
||||
pub fn OCSP_cert_to_id(
|
||||
dgst: *const ::EVP_MD,
|
||||
subject: *const ::X509,
|
||||
issuer: *const ::X509,
|
||||
) -> *mut ::OCSP_CERTID;
|
||||
|
||||
pub fn TLS_method() -> *const ::SSL_METHOD;
|
||||
pub fn DTLS_method() -> *const ::SSL_METHOD;
|
||||
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *const c_char;
|
||||
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
|
||||
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_get_ext_d2i(
|
||||
x: *const ::X509,
|
||||
nid: c_int,
|
||||
crit: *mut c_int,
|
||||
idx: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
pub fn X509_NAME_add_entry_by_NID(
|
||||
x: *mut ::X509_NAME,
|
||||
field: c_int,
|
||||
ty: c_int,
|
||||
bytes: *const c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
|
||||
pub fn X509_ALGOR_get0(
|
||||
paobj: *mut *const ::ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
ppval: *mut *const c_void,
|
||||
alg: *const ::X509_ALGOR,
|
||||
);
|
||||
pub fn X509_NAME_get_entry(n: *const ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
|
||||
pub fn X509_NAME_ENTRY_get_data(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
|
||||
pub fn X509V3_EXT_nconf_nid(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
ext_nid: c_int,
|
||||
value: *const c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn X509V3_EXT_nconf(
|
||||
conf: *mut ::CONF,
|
||||
ctx: *mut ::X509V3_CTX,
|
||||
name: *const c_char,
|
||||
value: *const c_char,
|
||||
) -> *mut ::X509_EXTENSION;
|
||||
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ::ASN1_STRING) -> c_int;
|
||||
pub fn BN_is_negative(b: *const ::BIGNUM) -> c_int;
|
||||
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
|
||||
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
|
||||
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
|
||||
pub fn EVP_PBE_scrypt(
|
||||
pass: *const c_char,
|
||||
passlen: size_t,
|
||||
salt: *const c_uchar,
|
||||
saltlen: size_t,
|
||||
N: u64,
|
||||
r: u64,
|
||||
p: u64,
|
||||
maxmem: u64,
|
||||
key: *mut c_uchar,
|
||||
keylen: size_t,
|
||||
) -> c_int;
|
||||
pub fn DSA_get0_pqg(
|
||||
d: *const ::DSA,
|
||||
p: *mut *const ::BIGNUM,
|
||||
q: *mut *const ::BIGNUM,
|
||||
q: *mut *const ::BIGNUM,
|
||||
);
|
||||
pub fn DSA_get0_key(
|
||||
d: *const ::DSA,
|
||||
pub_key: *mut *const ::BIGNUM,
|
||||
priv_key: *mut *const ::BIGNUM,
|
||||
);
|
||||
pub fn RSA_get0_key(
|
||||
r: *const ::RSA,
|
||||
n: *mut *const ::BIGNUM,
|
||||
e: *mut *const ::BIGNUM,
|
||||
d: *mut *const ::BIGNUM,
|
||||
);
|
||||
pub fn RSA_get0_factors(r: *const ::RSA, p: *mut *const ::BIGNUM, q: *mut *const ::BIGNUM);
|
||||
pub fn RSA_get0_crt_params(
|
||||
r: *const ::RSA,
|
||||
dmp1: *mut *const ::BIGNUM,
|
||||
dmq1: *mut *const ::BIGNUM,
|
||||
iqmp: *mut *const ::BIGNUM,
|
||||
);
|
||||
pub fn RSA_set0_key(
|
||||
r: *mut ::RSA,
|
||||
n: *mut ::BIGNUM,
|
||||
e: *mut ::BIGNUM,
|
||||
d: *mut ::BIGNUM,
|
||||
) -> c_int;
|
||||
pub fn RSA_set0_factors(r: *mut ::RSA, p: *mut ::BIGNUM, q: *mut ::BIGNUM) -> c_int;
|
||||
pub fn RSA_set0_crt_params(
|
||||
r: *mut ::RSA,
|
||||
dmp1: *mut ::BIGNUM,
|
||||
dmq1: *mut ::BIGNUM,
|
||||
iqmp: *mut ::BIGNUM,
|
||||
) -> c_int;
|
||||
pub fn ASN1_STRING_get0_data(x: *const ::ASN1_STRING) -> *const c_uchar;
|
||||
pub fn OPENSSL_sk_num(stack: *const ::OPENSSL_STACK) -> c_int;
|
||||
pub fn OPENSSL_sk_value(stack: *const ::OPENSSL_STACK, idx: c_int) -> *mut c_void;
|
||||
pub fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong;
|
||||
pub fn SSL_CTX_set_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong;
|
||||
pub fn SSL_CTX_clear_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong;
|
||||
pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME;
|
||||
pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME;
|
||||
pub fn X509_get0_signature(
|
||||
psig: *mut *const ::ASN1_BIT_STRING,
|
||||
palg: *mut *const ::X509_ALGOR,
|
||||
x: *const ::X509,
|
||||
);
|
||||
pub fn DH_set0_pqg(
|
||||
dh: *mut ::DH,
|
||||
p: *mut ::BIGNUM,
|
||||
q: *mut ::BIGNUM,
|
||||
g: *mut ::BIGNUM,
|
||||
) -> c_int;
|
||||
pub fn BIO_set_init(a: *mut ::BIO, init: c_int);
|
||||
pub fn BIO_set_data(a: *mut ::BIO, data: *mut c_void);
|
||||
pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void;
|
||||
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut ::BIO_METHOD;
|
||||
pub fn BIO_meth_free(biom: *mut ::BIO_METHOD);
|
||||
pub fn BIO_meth_set_write(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int,
|
||||
) -> c_int;
|
||||
pub fn BIO_meth_set_read(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int,
|
||||
) -> c_int;
|
||||
pub fn BIO_meth_set_puts(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int,
|
||||
) -> c_int;
|
||||
pub fn BIO_meth_set_ctrl(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
read: unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long,
|
||||
) -> c_int;
|
||||
pub fn BIO_meth_set_create(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
create: unsafe extern "C" fn(*mut ::BIO) -> c_int,
|
||||
) -> c_int;
|
||||
pub fn BIO_meth_set_destroy(
|
||||
biom: *mut ::BIO_METHOD,
|
||||
destroy: unsafe extern "C" fn(*mut ::BIO) -> c_int,
|
||||
) -> c_int;
|
||||
pub fn CRYPTO_get_ex_new_index(
|
||||
class_index: c_int,
|
||||
argl: c_long,
|
||||
argp: *mut c_void,
|
||||
new_func: Option<::CRYPTO_EX_new>,
|
||||
dup_func: Option<::CRYPTO_EX_dup>,
|
||||
free_func: Option<::CRYPTO_EX_free>,
|
||||
) -> c_int;
|
||||
pub fn X509_up_ref(x: *mut X509) -> c_int;
|
||||
pub fn SSL_CTX_up_ref(x: *mut SSL_CTX) -> c_int;
|
||||
pub fn SSL_session_reused(ssl: *mut SSL) -> c_int;
|
||||
pub fn SSL_SESSION_get_master_key(
|
||||
session: *const SSL_SESSION,
|
||||
out: *mut c_uchar,
|
||||
outlen: size_t,
|
||||
) -> size_t;
|
||||
pub fn SSL_SESSION_up_ref(ses: *mut SSL_SESSION) -> c_int;
|
||||
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
|
||||
pub fn X509_STORE_CTX_get0_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
|
||||
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
|
||||
pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn OpenSSL_version_num() -> c_ulong;
|
||||
pub fn OpenSSL_version(key: c_int) -> *const c_char;
|
||||
pub fn OPENSSL_init_ssl(opts: u64, settings: *const OPENSSL_INIT_SETTINGS) -> c_int;
|
||||
pub fn OPENSSL_sk_new_null() -> *mut ::OPENSSL_STACK;
|
||||
pub fn OPENSSL_sk_free(st: *mut ::OPENSSL_STACK);
|
||||
pub fn OPENSSL_sk_pop_free(
|
||||
st: *mut ::OPENSSL_STACK,
|
||||
free: Option<unsafe extern "C" fn(*mut c_void)>,
|
||||
);
|
||||
pub fn OPENSSL_sk_push(st: *mut ::OPENSSL_STACK, data: *const c_void) -> c_int;
|
||||
pub fn OPENSSL_sk_pop(st: *mut ::OPENSSL_STACK) -> *mut c_void;
|
||||
|
||||
pub fn PKCS12_create(
|
||||
pass: *const c_char,
|
||||
friendly_name: *const c_char,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
ca: *mut stack_st_X509,
|
||||
nid_key: c_int,
|
||||
nid_cert: c_int,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
keytype: c_int,
|
||||
) -> *mut PKCS12;
|
||||
pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long;
|
||||
pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut ::X509_NAME;
|
||||
}
|
||||
991
openssl-sys/src/ossl_typ.rs
Normal file
991
openssl-sys/src/ossl_typ.rs
Normal file
@ -0,0 +1,991 @@
|
||||
use libc::*;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use *;
|
||||
|
||||
pub enum ASN1_INTEGER {}
|
||||
pub enum ASN1_GENERALIZEDTIME {}
|
||||
pub enum ASN1_STRING {}
|
||||
pub enum ASN1_BIT_STRING {}
|
||||
pub enum ASN1_TIME {}
|
||||
pub enum ASN1_TYPE {}
|
||||
pub enum ASN1_OBJECT {}
|
||||
pub enum ASN1_OCTET_STRING {}
|
||||
|
||||
pub enum bio_st {} // FIXME remove
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum BIO {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct BIO {
|
||||
pub method: *mut BIO_METHOD,
|
||||
pub callback: Option<
|
||||
unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long) -> c_long,
|
||||
>,
|
||||
pub cb_arg: *mut c_char,
|
||||
pub init: c_int,
|
||||
pub shutdown: c_int,
|
||||
pub flags: c_int,
|
||||
pub retry_reason: c_int,
|
||||
pub num: c_int,
|
||||
pub ptr: *mut c_void,
|
||||
pub next_bio: *mut BIO,
|
||||
pub prev_bio: *mut BIO,
|
||||
pub references: c_int,
|
||||
pub num_read: c_ulong,
|
||||
pub num_write: c_ulong,
|
||||
pub ex_data: CRYPTO_EX_DATA,
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum BIGNUM {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct BIGNUM {
|
||||
pub d: *mut BN_ULONG,
|
||||
pub top: c_int,
|
||||
pub dmax: c_int,
|
||||
pub neg: c_int,
|
||||
pub flags: c_int,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum BN_BLINDING {}
|
||||
pub enum BN_MONT_CTX {}
|
||||
|
||||
pub enum BN_CTX {}
|
||||
pub enum BN_GENCB {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum EVP_CIPHER {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct EVP_CIPHER {
|
||||
pub nid: c_int,
|
||||
pub block_size: c_int,
|
||||
pub key_len: c_int,
|
||||
pub iv_len: c_int,
|
||||
pub flags: c_ulong,
|
||||
pub init: Option<
|
||||
unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *const c_uchar, *const c_uchar, c_int) -> c_int,
|
||||
>,
|
||||
pub do_cipher: Option<
|
||||
unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut c_uchar, *const c_uchar, size_t) -> c_int,
|
||||
>,
|
||||
pub cleanup: Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX) -> c_int>,
|
||||
pub ctx_size: c_int,
|
||||
pub set_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut ASN1_TYPE) -> c_int>,
|
||||
pub get_asn1_parameters:
|
||||
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut ASN1_TYPE) -> c_int>,
|
||||
pub ctrl:
|
||||
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
|
||||
pub app_data: *mut c_void,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum EVP_CIPHER_CTX {}
|
||||
pub enum EVP_MD {}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum EVP_MD_CTX {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct EVP_MD_CTX {
|
||||
digest: *mut EVP_MD,
|
||||
engine: *mut ENGINE,
|
||||
flags: c_ulong,
|
||||
md_data: *mut c_void,
|
||||
pctx: *mut EVP_PKEY_CTX,
|
||||
update: *mut c_void,
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum EVP_PKEY {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct EVP_PKEY {
|
||||
pub type_: c_int,
|
||||
pub save_type: c_int,
|
||||
pub references: c_int,
|
||||
pub ameth: *const EVP_PKEY_ASN1_METHOD,
|
||||
pub engine: *mut ENGINE,
|
||||
pub pkey: *mut c_void,
|
||||
pub save_parameters: c_int,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum EVP_PKEY_ASN1_METHOD {}
|
||||
|
||||
pub enum EVP_PKEY_CTX {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum HMAC_CTX {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct HMAC_CTX {
|
||||
md: *mut EVP_MD,
|
||||
md_ctx: EVP_MD_CTX,
|
||||
i_ctx: EVP_MD_CTX,
|
||||
o_ctx: EVP_MD_CTX,
|
||||
key_length: c_uint,
|
||||
key: [c_uchar; 128],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum DH {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct DH {
|
||||
pub pad: c_int,
|
||||
pub version: c_int,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub g: *mut ::BIGNUM,
|
||||
pub length: c_long,
|
||||
pub pub_key: *mut ::BIGNUM,
|
||||
pub priv_key: *mut ::BIGNUM,
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut ::BN_MONT_CTX,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub j: *mut ::BIGNUM,
|
||||
pub seed: *mut c_uchar,
|
||||
pub seedlen: c_int,
|
||||
pub counter: *mut ::BIGNUM,
|
||||
pub references: c_int,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub meth: *const ::DH_METHOD,
|
||||
pub engine: *mut ::ENGINE,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum DH_METHOD {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum DSA {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct DSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub write_params: c_int,
|
||||
|
||||
pub p: *mut BIGNUM,
|
||||
pub q: *mut BIGNUM,
|
||||
pub g: *mut BIGNUM,
|
||||
pub pub_key: *mut BIGNUM,
|
||||
pub priv_key: *mut BIGNUM,
|
||||
pub kinv: *mut BIGNUM,
|
||||
pub r: *mut BIGNUM,
|
||||
|
||||
pub flags: c_int,
|
||||
pub method_mont_p: *mut BN_MONT_CTX,
|
||||
pub references: c_int,
|
||||
pub ex_data: CRYPTO_EX_DATA,
|
||||
pub meth: *const DSA_METHOD,
|
||||
pub engine: *mut ENGINE,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum DSA_METHOD {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum RSA {}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct RSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub meth: *const ::RSA_METHOD,
|
||||
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub n: *mut ::BIGNUM,
|
||||
pub e: *mut ::BIGNUM,
|
||||
pub d: *mut ::BIGNUM,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub dmp1: *mut ::BIGNUM,
|
||||
pub dmq1: *mut ::BIGNUM,
|
||||
pub iqmp: *mut ::BIGNUM,
|
||||
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub references: c_int,
|
||||
pub flags: c_int,
|
||||
|
||||
pub _method_mod_n: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_p: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_q: *mut ::BN_MONT_CTX,
|
||||
|
||||
pub blinding: *mut ::BN_BLINDING,
|
||||
pub mt_blinding: *mut ::BN_BLINDING,
|
||||
}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct RSA {
|
||||
pub pad: c_int,
|
||||
pub version: c_long,
|
||||
pub meth: *const ::RSA_METHOD,
|
||||
|
||||
pub engine: *mut ::ENGINE,
|
||||
pub n: *mut ::BIGNUM,
|
||||
pub e: *mut ::BIGNUM,
|
||||
pub d: *mut ::BIGNUM,
|
||||
pub p: *mut ::BIGNUM,
|
||||
pub q: *mut ::BIGNUM,
|
||||
pub dmp1: *mut ::BIGNUM,
|
||||
pub dmq1: *mut ::BIGNUM,
|
||||
pub iqmp: *mut ::BIGNUM,
|
||||
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub references: c_int,
|
||||
pub flags: c_int,
|
||||
|
||||
pub _method_mod_n: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_p: *mut ::BN_MONT_CTX,
|
||||
pub _method_mod_q: *mut ::BN_MONT_CTX,
|
||||
|
||||
pub bignum_data: *mut c_char,
|
||||
pub blinding: *mut ::BN_BLINDING,
|
||||
pub mt_blinding: *mut ::BN_BLINDING,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum RSA_METHOD {}
|
||||
|
||||
pub enum EC_KEY {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum X509 {}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct X509 {
|
||||
pub cert_info: *mut X509_CINF,
|
||||
pub sig_alg: *mut ::X509_ALGOR,
|
||||
pub signature: *mut ::ASN1_BIT_STRING,
|
||||
pub valid: c_int,
|
||||
pub references: c_int,
|
||||
pub name: *mut c_char,
|
||||
pub ex_data: ::CRYPTO_EX_DATA,
|
||||
pub ex_pathlen: c_long,
|
||||
pub ex_pcpathlen: c_long,
|
||||
pub ex_flags: c_ulong,
|
||||
pub ex_kusage: c_ulong,
|
||||
pub ex_xkusage: c_ulong,
|
||||
pub ex_nscert: c_ulong,
|
||||
skid: *mut c_void,
|
||||
akid: *mut c_void,
|
||||
policy_cache: *mut c_void,
|
||||
crldp: *mut c_void,
|
||||
altname: *mut c_void,
|
||||
nc: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
|
||||
sha1_hash: [c_uchar; 20],
|
||||
aux: *mut c_void,
|
||||
}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct X509 {
|
||||
pub cert_info: *mut X509_CINF,
|
||||
pub sig_alg: *mut X509_ALGOR,
|
||||
pub signature: *mut ASN1_BIT_STRING,
|
||||
pub valid: c_int,
|
||||
pub references: c_int,
|
||||
pub name: *mut c_char,
|
||||
pub ex_data: CRYPTO_EX_DATA,
|
||||
pub ex_pathlen: c_long,
|
||||
pub ex_pcpathlen: c_long,
|
||||
pub ex_flags: c_ulong,
|
||||
pub ex_kusage: c_ulong,
|
||||
pub ex_xkusage: c_ulong,
|
||||
pub ex_nscert: c_ulong,
|
||||
skid: *mut c_void,
|
||||
akid: *mut c_void,
|
||||
policy_cache: *mut c_void,
|
||||
crldp: *mut c_void,
|
||||
altname: *mut c_void,
|
||||
nc: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
|
||||
rfc3779_addr: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
|
||||
rfc3779_asid: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
|
||||
sha1_hash: [c_uchar; 20],
|
||||
aux: *mut c_void,
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum X509_ALGOR {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct X509_ALGOR {
|
||||
pub algorithm: *mut ::ASN1_OBJECT,
|
||||
parameter: *mut c_void,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub enum X509_CRL {}
|
||||
pub enum X509_NAME {}
|
||||
pub enum X509_STORE {}
|
||||
pub enum X509_STORE_CTX {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum X509_VERIFY_PARAM {}
|
||||
} else if #[cfg(libressl251)] {
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
id: *mut c_void,
|
||||
}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
//pub id: *mut X509_VERIFY_PARAM_ID,
|
||||
}
|
||||
} else if #[cfg(ossl102)] {
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
pub inh_flags: c_ulong,
|
||||
pub flags: c_ulong,
|
||||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
pub id: *mut X509_VERIFY_PARAM_ID,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509V3_CTX {
|
||||
flags: c_int,
|
||||
issuer_cert: *mut c_void,
|
||||
subject_cert: *mut c_void,
|
||||
subject_req: *mut c_void,
|
||||
crl: *mut c_void,
|
||||
db_meth: *mut c_void,
|
||||
db: *mut c_void,
|
||||
// I like the last comment line, it is copied from OpenSSL sources:
|
||||
// Maybe more here
|
||||
}
|
||||
pub enum CONF {}
|
||||
#[cfg(ossl110)]
|
||||
pub enum OPENSSL_INIT_SETTINGS {}
|
||||
|
||||
pub enum ENGINE {}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum SSL {}
|
||||
} else if #[cfg(libressl251)] {
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut ::BIO,
|
||||
wbio: *mut ::BIO,
|
||||
bbio: *mut ::BIO,
|
||||
pub server: c_int,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
verify_mode: c_int,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
verify_result: c_long,
|
||||
references: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
tlsext_hostname: *mut c_char,
|
||||
tlsext_status_type: c_int,
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut EVP_MD_CTX,
|
||||
internal: *mut c_void,
|
||||
}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
type_: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut c_void,
|
||||
wbio: *mut c_void,
|
||||
bbio: *mut c_void,
|
||||
rwstate: c_int,
|
||||
in_handshake: c_int,
|
||||
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
|
||||
pub server: c_int,
|
||||
new_session: c_int,
|
||||
quiet_shutdown: c_int,
|
||||
shutdown: c_int,
|
||||
state: c_int,
|
||||
rstate: c_int,
|
||||
init_buf: *mut c_void,
|
||||
init_msg: *mut c_void,
|
||||
init_num: c_int,
|
||||
init_off: c_int,
|
||||
packet: *mut c_uchar,
|
||||
packet_length: c_uint,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: Option<
|
||||
unsafe extern "C" fn(c_int,
|
||||
c_int,
|
||||
c_int,
|
||||
*const c_void,
|
||||
size_t,
|
||||
*mut SSL,
|
||||
*mut c_void),
|
||||
>,
|
||||
msg_callback_arg: *mut c_void,
|
||||
hit: c_int,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
|
||||
mac_flags: c_int,
|
||||
aead_read_ctx: *mut c_void,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut ::EVP_MD_CTX,
|
||||
aead_write_ctx: *mut c_void,
|
||||
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
write_hash: *mut ::EVP_MD_CTX,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
generate_session_id: ::GEN_SESSION_CB,
|
||||
verify_mode: c_int,
|
||||
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
|
||||
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
debug: c_int,
|
||||
verify_result: c_long,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
client_CA: *mut stack_st_X509_NAME,
|
||||
references: c_int,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
first_packet: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
tlsext_debug_cb:
|
||||
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
|
||||
tlsext_debug_arg: *mut c_void,
|
||||
tlsext_hostname: *mut c_char,
|
||||
servername_done: c_int,
|
||||
tlsext_status_type: c_int,
|
||||
tlsext_status_expected: c_int,
|
||||
tlsext_ocsp_ids: *mut c_void,
|
||||
tlsext_ocsp_exts: *mut c_void,
|
||||
tlsext_ocsp_resp: *mut c_uchar,
|
||||
tlsext_ocsp_resplen: c_int,
|
||||
tlsext_ticket_expected: c_int,
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
tlsext_session_ticket: *mut c_void,
|
||||
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
|
||||
tls_session_ticket_ext_cb_arg: *mut c_void,
|
||||
tls_session_secret_cb: ::tls_session_secret_cb_fn,
|
||||
tls_session_secret_cb_arg: *mut c_void,
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
next_proto_negotiated: *mut c_uchar,
|
||||
next_proto_negotiated_len: c_uchar,
|
||||
srtp_profiles: *mut c_void,
|
||||
srtp_profile: *mut c_void,
|
||||
tlsext_heartbeat: c_uint,
|
||||
tlsext_hb_pending: c_uint,
|
||||
tlsext_hb_seq: c_uint,
|
||||
alpn_client_proto_list: *mut c_uchar,
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
renegotiate: c_int,
|
||||
}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct SSL {
|
||||
version: c_int,
|
||||
type_: c_int,
|
||||
method: *const ::SSL_METHOD,
|
||||
rbio: *mut c_void,
|
||||
wbio: *mut c_void,
|
||||
bbio: *mut c_void,
|
||||
rwstate: c_int,
|
||||
in_handshake: c_int,
|
||||
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
|
||||
pub server: c_int,
|
||||
new_session: c_int,
|
||||
quiet_session: c_int,
|
||||
shutdown: c_int,
|
||||
state: c_int,
|
||||
rstate: c_int,
|
||||
init_buf: *mut c_void,
|
||||
init_msg: *mut c_void,
|
||||
init_num: c_int,
|
||||
init_off: c_int,
|
||||
packet: *mut c_uchar,
|
||||
packet_length: c_uint,
|
||||
s2: *mut c_void,
|
||||
s3: *mut c_void,
|
||||
d1: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: Option<
|
||||
unsafe extern "C" fn(c_int, c_int, c_int, *const c_void, size_t, *mut SSL, *mut c_void),
|
||||
>,
|
||||
msg_callback_arg: *mut c_void,
|
||||
hit: c_int,
|
||||
param: *mut c_void,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
|
||||
mac_flags: c_int,
|
||||
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
read_hash: *mut ::EVP_MD_CTX,
|
||||
expand: *mut c_void,
|
||||
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
|
||||
write_hash: *mut ::EVP_MD_CTX,
|
||||
compress: *mut c_void,
|
||||
cert: *mut c_void,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
session: *mut ::SSL_SESSION,
|
||||
generate_session_id: ::GEN_SESSION_CB,
|
||||
verify_mode: c_int,
|
||||
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
|
||||
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
|
||||
error: c_int,
|
||||
error_code: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
kssl_ctx: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_client_callback: Option<
|
||||
unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint)
|
||||
-> c_uint,
|
||||
>,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_server_callback:
|
||||
Option<unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint>,
|
||||
ctx: *mut ::SSL_CTX,
|
||||
debug: c_int,
|
||||
verify_result: c_long,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
client_CA: *mut stack_st_X509_NAME,
|
||||
references: c_int,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
first_packet: c_int,
|
||||
client_version: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_debug_cb:
|
||||
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_debug_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hostname: *mut c_char,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
servername_done: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_type: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_expected: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_ids: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_exts: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_resp: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ocsp_resplen: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticket_expected: c_int,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC")
|
||||
))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC")
|
||||
))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC")
|
||||
))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC")
|
||||
))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_len: size_t,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_session_ticket: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_ticket_ext_cb_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_secret_cb: ::tls_session_secret_cb_fn,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tls_session_secret_cb_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
initial_ctx: *mut ::SSL_CTX,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_proto_negotiated: *mut c_uchar,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_proto_negotiated_len: c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
srtp_profiles: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
srtp_profile: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_heartbeat: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hb_pending: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hb_seq: c_uint,
|
||||
renegotiate: c_int,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_ctx: ::SRP_CTX,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum SSL_CTX {}
|
||||
} else if #[cfg(libressl251)] {
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *const ::SSL_METHOD,
|
||||
cipher_list: *mut stack_st_SSL_CIPHER,
|
||||
cert_store: *mut c_void,
|
||||
session_timeout: c_long,
|
||||
pub references: c_int,
|
||||
extra_certs: *mut stack_st_X509,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
param: *mut ::X509_VERIFY_PARAM,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
internal: *mut c_void,
|
||||
}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *mut c_void,
|
||||
cipher_list: *mut c_void,
|
||||
cipher_list_by_id: *mut c_void,
|
||||
cert_store: *mut c_void,
|
||||
sessions: *mut c_void,
|
||||
session_cache_size: c_ulong,
|
||||
session_cache_head: *mut c_void,
|
||||
session_cache_tail: *mut c_void,
|
||||
session_cache_mode: c_int,
|
||||
session_timeout: c_long,
|
||||
new_session_cb: *mut c_void,
|
||||
remove_session_cb: *mut c_void,
|
||||
get_session_cb: *mut c_void,
|
||||
stats: [c_int; 11],
|
||||
pub references: c_int,
|
||||
app_verify_callback: *mut c_void,
|
||||
app_verify_arg: *mut c_void,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
client_cert_cb: *mut c_void,
|
||||
app_gen_cookie_cb: *mut c_void,
|
||||
app_verify_cookie_cb: *mut c_void,
|
||||
ex_dat: ::CRYPTO_EX_DATA,
|
||||
rsa_md5: *mut c_void,
|
||||
md5: *mut c_void,
|
||||
sha1: *mut c_void,
|
||||
extra_certs: *mut c_void,
|
||||
comp_methods: *mut c_void,
|
||||
info_callback: *mut c_void,
|
||||
client_CA: *mut c_void,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
cert: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: *mut c_void,
|
||||
msg_callback_arg: *mut c_void,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; 32],
|
||||
default_verify_callback: *mut c_void,
|
||||
generate_session_id: *mut c_void,
|
||||
param: *mut c_void,
|
||||
quiet_shutdown: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
|
||||
client_cert_engine: *mut c_void,
|
||||
|
||||
tlsext_servername_callback: *mut c_void,
|
||||
tlsect_servername_arg: *mut c_void,
|
||||
tlsext_tick_key_name: [c_uchar; 16],
|
||||
tlsext_tick_hmac_key: [c_uchar; 16],
|
||||
tlsext_tick_aes_key: [c_uchar; 16],
|
||||
tlsext_ticket_key_cb: *mut c_void,
|
||||
tlsext_status_cb: *mut c_void,
|
||||
tlsext_status_arg: *mut c_void,
|
||||
tlsext_opaque_prf_input_callback: *mut c_void,
|
||||
tlsext_opaque_prf_input_callback_arg: *mut c_void,
|
||||
|
||||
next_protos_advertised_cb: *mut c_void,
|
||||
next_protos_advertised_cb_arg: *mut c_void,
|
||||
next_proto_select_cb: *mut c_void,
|
||||
next_proto_select_cb_arg: *mut c_void,
|
||||
|
||||
srtp_profiles: *mut c_void,
|
||||
}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct SSL_CTX {
|
||||
method: *mut c_void,
|
||||
cipher_list: *mut c_void,
|
||||
cipher_list_by_id: *mut c_void,
|
||||
cert_store: *mut c_void,
|
||||
sessions: *mut c_void,
|
||||
session_cache_size: c_ulong,
|
||||
session_cache_head: *mut c_void,
|
||||
session_cache_tail: *mut c_void,
|
||||
session_cache_mode: c_int,
|
||||
session_timeout: c_long,
|
||||
new_session_cb: *mut c_void,
|
||||
remove_session_cb: *mut c_void,
|
||||
get_session_cb: *mut c_void,
|
||||
stats: [c_int; 11],
|
||||
pub references: c_int,
|
||||
app_verify_callback: *mut c_void,
|
||||
app_verify_arg: *mut c_void,
|
||||
default_passwd_callback: *mut c_void,
|
||||
default_passwd_callback_userdata: *mut c_void,
|
||||
client_cert_cb: *mut c_void,
|
||||
app_gen_cookie_cb: *mut c_void,
|
||||
app_verify_cookie_cb: *mut c_void,
|
||||
ex_dat: ::CRYPTO_EX_DATA,
|
||||
rsa_md5: *mut c_void,
|
||||
md5: *mut c_void,
|
||||
sha1: *mut c_void,
|
||||
extra_certs: *mut c_void,
|
||||
comp_methods: *mut c_void,
|
||||
info_callback: *mut c_void,
|
||||
client_CA: *mut c_void,
|
||||
options: c_ulong,
|
||||
mode: c_ulong,
|
||||
max_cert_list: c_long,
|
||||
cert: *mut c_void,
|
||||
read_ahead: c_int,
|
||||
msg_callback: *mut c_void,
|
||||
msg_callback_arg: *mut c_void,
|
||||
verify_mode: c_int,
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; 32],
|
||||
default_verify_callback: *mut c_void,
|
||||
generate_session_id: *mut c_void,
|
||||
param: *mut c_void,
|
||||
quiet_shutdown: c_int,
|
||||
max_send_fragment: c_uint,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
|
||||
client_cert_engine: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_servername_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsect_servername_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_key_name: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_hmac_key: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_aes_key: [c_uchar; 16],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticket_key_cb: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_cb: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_status_arg: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_opaque_prf_input_callback_arg: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity_hint: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_client_callback: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_server_callback: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
freelist_max_len: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
wbuf_freelist: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
|
||||
rbuf_freelist: *mut c_void,
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_ctx: SRP_CTX,
|
||||
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_protos_advertised_cb: *mut c_void,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_protos_advertised_cb_arg: *mut c_void,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_proto_select_cb: *mut c_void,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
|
||||
))]
|
||||
next_proto_select_cb_arg: *mut c_void,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
|
||||
srtp_profiles: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_select_cb: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_select_cb_arg: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_client_proto_list_len: c_uint,
|
||||
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC"),
|
||||
ossl102
|
||||
))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC"),
|
||||
ossl102
|
||||
))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC"),
|
||||
ossl102
|
||||
))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(
|
||||
not(osslconf = "OPENSSL_NO_TLSEXT"),
|
||||
not(osslconf = "OPENSSL_NO_EC"),
|
||||
ossl102
|
||||
))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
pub struct SRP_CTX {
|
||||
SRP_cb_arg: *mut c_void,
|
||||
TLS_ext_srp_username_callback: *mut c_void,
|
||||
SRP_verify_param_callback: *mut c_void,
|
||||
SRP_give_srp_client_pwd_callback: *mut c_void,
|
||||
login: *mut c_void,
|
||||
N: *mut c_void,
|
||||
g: *mut c_void,
|
||||
s: *mut c_void,
|
||||
B: *mut c_void,
|
||||
A: *mut c_void,
|
||||
a: *mut c_void,
|
||||
b: *mut c_void,
|
||||
v: *mut c_void,
|
||||
info: *mut c_void,
|
||||
stringth: c_int,
|
||||
srp_Mask: c_ulong,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum COMP_METHOD {}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
pub enum CRYPTO_EX_DATA {}
|
||||
} else if #[cfg(libressl)] {
|
||||
#[repr(C)]
|
||||
pub struct CRYPTO_EX_DATA {
|
||||
pub sk: *mut ::stack_st_void,
|
||||
}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct CRYPTO_EX_DATA {
|
||||
pub sk: *mut stack_st_void,
|
||||
pub dummy: c_int,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum OCSP_RESPONSE {}
|
||||
161
openssl-sys/src/pem.rs
Normal file
161
openssl-sys/src/pem.rs
Normal file
@ -0,0 +1,161 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub type pem_password_cb = Option<
|
||||
unsafe extern "C" fn(
|
||||
buf: *mut c_char,
|
||||
size: c_int,
|
||||
rwflag: c_int,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int,
|
||||
>;
|
||||
|
||||
extern "C" {
|
||||
pub fn PEM_read_bio_X509(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut X509,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut X509;
|
||||
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
|
||||
pub fn PEM_read_bio_X509_REQ(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut X509_REQ,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut X509_REQ;
|
||||
pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: *mut X509_REQ) -> c_int;
|
||||
pub fn PEM_read_bio_RSAPrivateKey(
|
||||
bio: *mut BIO,
|
||||
rsa: *mut *mut RSA,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
pub fn PEM_write_bio_RSAPrivateKey(
|
||||
bp: *mut BIO,
|
||||
rsa: *mut RSA,
|
||||
cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_uchar,
|
||||
klen: c_int,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int;
|
||||
pub fn PEM_read_bio_RSAPublicKey(
|
||||
bio: *mut BIO,
|
||||
rsa: *mut *mut RSA,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
pub fn PEM_write_bio_RSAPublicKey(bp: *mut BIO, rsa: *const RSA) -> c_int;
|
||||
pub fn PEM_read_bio_RSA_PUBKEY(
|
||||
bio: *mut BIO,
|
||||
rsa: *mut *mut RSA,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
pub fn PEM_write_bio_RSA_PUBKEY(bp: *mut BIO, rsa: *mut RSA) -> c_int;
|
||||
pub fn PEM_read_bio_DSAPrivateKey(
|
||||
bp: *mut BIO,
|
||||
dsa: *mut *mut DSA,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut DSA;
|
||||
pub fn PEM_write_bio_DSAPrivateKey(
|
||||
bp: *mut BIO,
|
||||
dsa: *mut DSA,
|
||||
cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_uchar,
|
||||
klen: c_int,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int;
|
||||
pub fn PEM_read_bio_DSA_PUBKEY(
|
||||
bp: *mut BIO,
|
||||
dsa: *mut *mut DSA,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut DSA;
|
||||
pub fn PEM_write_bio_DSA_PUBKEY(bp: *mut BIO, dsa: *mut DSA) -> c_int;
|
||||
pub fn PEM_read_bio_ECPrivateKey(
|
||||
bio: *mut BIO,
|
||||
key: *mut *mut EC_KEY,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut EC_KEY;
|
||||
pub fn PEM_write_bio_ECPrivateKey(
|
||||
bio: *mut BIO,
|
||||
key: *mut EC_KEY,
|
||||
cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_uchar,
|
||||
klen: c_int,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int;
|
||||
pub fn PEM_read_bio_DHparams(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut DH,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut DH;
|
||||
pub fn PEM_write_bio_DHparams(bio: *mut BIO, x: *const DH) -> c_int;
|
||||
pub fn PEM_read_bio_PrivateKey(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut EVP_PKEY,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut EVP_PKEY;
|
||||
pub fn PEM_write_bio_PrivateKey(
|
||||
bio: *mut BIO,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_uchar,
|
||||
klen: c_int,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int;
|
||||
pub fn PEM_read_bio_PUBKEY(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut EVP_PKEY,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut EVP_PKEY;
|
||||
pub fn PEM_write_bio_PUBKEY(bp: *mut BIO, x: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn PEM_write_bio_PKCS8PrivateKey(
|
||||
bio: *mut BIO,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_char,
|
||||
klen: c_int,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> c_int;
|
||||
pub fn d2i_PKCS8PrivateKey_bio(
|
||||
bp: *mut BIO,
|
||||
x: *mut *mut EVP_PKEY,
|
||||
cb: pem_password_cb,
|
||||
u: *mut c_void,
|
||||
) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn PEM_read_bio_PKCS7(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut PKCS7,
|
||||
cb: pem_password_cb,
|
||||
u: *mut c_void,
|
||||
) -> *mut PKCS7;
|
||||
|
||||
pub fn PEM_write_bio_PKCS7(bp: *mut BIO, x: *mut PKCS7) -> c_int;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn PEM_read_bio_CMS(
|
||||
bio: *mut BIO,
|
||||
out: *mut *mut CMS_ContentInfo,
|
||||
callback: pem_password_cb,
|
||||
user_data: *mut c_void,
|
||||
) -> *mut CMS_ContentInfo;
|
||||
#[cfg(ossl101)]
|
||||
pub fn PEM_write_bio_CMS(bio: *mut BIO, cms: *const CMS_ContentInfo) -> c_int;
|
||||
}
|
||||
|
||||
pub const PEM_R_NO_START_LINE: c_int = 108;
|
||||
56
openssl-sys/src/pkcs12.rs
Normal file
56
openssl-sys/src/pkcs12.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub enum PKCS12 {}
|
||||
|
||||
extern "C" {
|
||||
pub fn PKCS12_free(p12: *mut PKCS12);
|
||||
pub fn i2d_PKCS12(a: *mut PKCS12, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_PKCS12(a: *mut *mut PKCS12, pp: *mut *const u8, length: c_long) -> *mut PKCS12;
|
||||
|
||||
pub fn PKCS12_parse(
|
||||
p12: *mut PKCS12,
|
||||
pass: *const c_char,
|
||||
pkey: *mut *mut EVP_PKEY,
|
||||
cert: *mut *mut X509,
|
||||
ca: *mut *mut stack_st_X509,
|
||||
) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn PKCS12_create(
|
||||
pass: *const c_char,
|
||||
friendly_name: *const c_char,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
ca: *mut stack_st_X509,
|
||||
nid_key: c_int,
|
||||
nid_cert: c_int,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
keytype: c_int,
|
||||
) -> *mut PKCS12;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn PKCS12_create(
|
||||
pass: *mut c_char,
|
||||
friendly_name: *mut c_char,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
ca: *mut stack_st_X509,
|
||||
nid_key: c_int,
|
||||
nid_cert: c_int,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
keytype: c_int,
|
||||
) -> *mut PKCS12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn i2d_PKCS12_bio(b: *mut BIO, a: *mut PKCS12) -> c_int;
|
||||
}
|
||||
74
openssl-sys/src/pkcs7.rs
Normal file
74
openssl-sys/src/pkcs7.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub enum PKCS7_SIGNED {}
|
||||
pub enum PKCS7_ENVELOPE {}
|
||||
pub enum PKCS7_SIGN_ENVELOPE {}
|
||||
pub enum PKCS7_DIGEST {}
|
||||
pub enum PKCS7_ENCRYPT {}
|
||||
pub enum PKCS7 {}
|
||||
|
||||
pub const PKCS7_TEXT: c_int = 0x1;
|
||||
pub const PKCS7_NOCERTS: c_int = 0x2;
|
||||
pub const PKCS7_NOSIGS: c_int = 0x4;
|
||||
pub const PKCS7_NOCHAIN: c_int = 0x8;
|
||||
pub const PKCS7_NOINTERN: c_int = 0x10;
|
||||
pub const PKCS7_NOVERIFY: c_int = 0x20;
|
||||
pub const PKCS7_DETACHED: c_int = 0x40;
|
||||
pub const PKCS7_BINARY: c_int = 0x80;
|
||||
pub const PKCS7_NOATTR: c_int = 0x100;
|
||||
pub const PKCS7_NOSMIMECAP: c_int = 0x200;
|
||||
pub const PKCS7_NOOLDMIMETYPE: c_int = 0x400;
|
||||
pub const PKCS7_CRLFEOL: c_int = 0x800;
|
||||
pub const PKCS7_STREAM: c_int = 0x1000;
|
||||
pub const PKCS7_NOCRL: c_int = 0x2000;
|
||||
pub const PKCS7_PARTIAL: c_int = 0x4000;
|
||||
pub const PKCS7_REUSE_DIGEST: c_int = 0x8000;
|
||||
#[cfg(not(any(ossl101, ossl102, libressl)))]
|
||||
pub const PKCS7_NO_DUAL_CONTENT: c_int = 0x10000;
|
||||
|
||||
extern "C" {
|
||||
pub fn PKCS7_encrypt(
|
||||
certs: *mut stack_st_X509,
|
||||
b: *mut BIO,
|
||||
cipher: *const EVP_CIPHER,
|
||||
flags: c_int,
|
||||
) -> *mut PKCS7;
|
||||
|
||||
pub fn PKCS7_verify(
|
||||
pkcs7: *mut PKCS7,
|
||||
certs: *mut stack_st_X509,
|
||||
store: *mut X509_STORE,
|
||||
indata: *mut BIO,
|
||||
out: *mut BIO,
|
||||
flags: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn PKCS7_sign(
|
||||
signcert: *mut X509,
|
||||
pkey: *mut EVP_PKEY,
|
||||
certs: *mut stack_st_X509,
|
||||
data: *mut BIO,
|
||||
flags: c_int,
|
||||
) -> *mut PKCS7;
|
||||
|
||||
pub fn PKCS7_decrypt(
|
||||
pkcs7: *mut PKCS7,
|
||||
pkey: *mut EVP_PKEY,
|
||||
cert: *mut X509,
|
||||
data: *mut BIO,
|
||||
flags: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn PKCS7_free(pkcs7: *mut PKCS7);
|
||||
|
||||
pub fn SMIME_write_PKCS7(
|
||||
out: *mut BIO,
|
||||
pkcs7: *mut PKCS7,
|
||||
data: *mut BIO,
|
||||
flags: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn SMIME_read_PKCS7(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut PKCS7;
|
||||
}
|
||||
10
openssl-sys/src/rand.rs
Normal file
10
openssl-sys/src/rand.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use libc::*;
|
||||
|
||||
extern "C" {
|
||||
pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int;
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn RAND_keep_random_devices_open(keep: c_int);
|
||||
|
||||
pub fn RAND_status() -> c_int;
|
||||
}
|
||||
179
openssl-sys/src/rsa.rs
Normal file
179
openssl-sys/src/rsa.rs
Normal file
@ -0,0 +1,179 @@
|
||||
use libc::*;
|
||||
use std::ptr;
|
||||
|
||||
use *;
|
||||
|
||||
pub const RSA_F4: c_long = 0x10001;
|
||||
|
||||
pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(
|
||||
ctx,
|
||||
EVP_PKEY_RSA,
|
||||
-1,
|
||||
EVP_PKEY_CTRL_RSA_PADDING,
|
||||
pad,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(
|
||||
ctx,
|
||||
EVP_PKEY_RSA,
|
||||
-1,
|
||||
EVP_PKEY_CTRL_GET_RSA_PADDING,
|
||||
0,
|
||||
ppad as *mut c_void,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(
|
||||
ctx,
|
||||
EVP_PKEY_RSA,
|
||||
EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY,
|
||||
EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
|
||||
len,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(
|
||||
ctx,
|
||||
EVP_PKEY_RSA,
|
||||
EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
|
||||
EVP_PKEY_CTRL_RSA_MGF1_MD,
|
||||
0,
|
||||
md as *mut c_void,
|
||||
)
|
||||
}
|
||||
|
||||
pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1;
|
||||
pub const EVP_PKEY_CTRL_RSA_PSS_SALTLEN: c_int = EVP_PKEY_ALG_CTRL + 2;
|
||||
|
||||
pub const EVP_PKEY_CTRL_RSA_MGF1_MD: c_int = EVP_PKEY_ALG_CTRL + 5;
|
||||
|
||||
pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6;
|
||||
|
||||
pub const RSA_PKCS1_PADDING: c_int = 1;
|
||||
pub const RSA_SSLV23_PADDING: c_int = 2;
|
||||
pub const RSA_NO_PADDING: c_int = 3;
|
||||
pub const RSA_PKCS1_OAEP_PADDING: c_int = 4;
|
||||
pub const RSA_X931_PADDING: c_int = 5;
|
||||
pub const RSA_PKCS1_PSS_PADDING: c_int = 6;
|
||||
|
||||
extern "C" {
|
||||
pub fn RSA_new() -> *mut RSA;
|
||||
pub fn RSA_size(k: *const RSA) -> c_int;
|
||||
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_set0_key(
|
||||
r: *mut ::RSA,
|
||||
n: *mut ::BIGNUM,
|
||||
e: *mut ::BIGNUM,
|
||||
d: *mut ::BIGNUM,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_set0_factors(r: *mut ::RSA, p: *mut ::BIGNUM, q: *mut ::BIGNUM) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_set0_crt_params(
|
||||
r: *mut ::RSA,
|
||||
dmp1: *mut ::BIGNUM,
|
||||
dmq1: *mut ::BIGNUM,
|
||||
iqmp: *mut ::BIGNUM,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_get0_key(
|
||||
r: *const ::RSA,
|
||||
n: *mut *const ::BIGNUM,
|
||||
e: *mut *const ::BIGNUM,
|
||||
d: *mut *const ::BIGNUM,
|
||||
);
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_get0_factors(r: *const ::RSA, p: *mut *const ::BIGNUM, q: *mut *const ::BIGNUM);
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn RSA_get0_crt_params(
|
||||
r: *const ::RSA,
|
||||
dmp1: *mut *const ::BIGNUM,
|
||||
dmq1: *mut *const ::BIGNUM,
|
||||
iqmp: *mut *const ::BIGNUM,
|
||||
);
|
||||
|
||||
#[cfg(not(ossl110))]
|
||||
pub fn RSA_generate_key(
|
||||
modsz: c_int,
|
||||
e: c_ulong,
|
||||
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
|
||||
cbarg: *mut c_void,
|
||||
) -> *mut RSA;
|
||||
|
||||
pub fn RSA_generate_key_ex(
|
||||
rsa: *mut RSA,
|
||||
bits: c_int,
|
||||
e: *mut BIGNUM,
|
||||
cb: *mut BN_GENCB,
|
||||
) -> c_int;
|
||||
|
||||
pub fn RSA_public_encrypt(
|
||||
flen: c_int,
|
||||
from: *const u8,
|
||||
to: *mut u8,
|
||||
k: *mut RSA,
|
||||
pad: c_int,
|
||||
) -> c_int;
|
||||
pub fn RSA_private_encrypt(
|
||||
flen: c_int,
|
||||
from: *const u8,
|
||||
to: *mut u8,
|
||||
k: *mut RSA,
|
||||
pad: c_int,
|
||||
) -> c_int;
|
||||
pub fn RSA_public_decrypt(
|
||||
flen: c_int,
|
||||
from: *const u8,
|
||||
to: *mut u8,
|
||||
k: *mut RSA,
|
||||
pad: c_int,
|
||||
) -> c_int;
|
||||
pub fn RSA_private_decrypt(
|
||||
flen: c_int,
|
||||
from: *const u8,
|
||||
to: *mut u8,
|
||||
k: *mut RSA,
|
||||
pad: c_int,
|
||||
) -> c_int;
|
||||
pub fn RSA_check_key(r: *const ::RSA) -> c_int;
|
||||
pub fn RSA_free(rsa: *mut RSA);
|
||||
pub fn RSA_up_ref(rsa: *mut RSA) -> c_int;
|
||||
|
||||
pub fn i2d_RSAPublicKey(k: *const RSA, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_RSAPublicKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
|
||||
pub fn i2d_RSAPrivateKey(k: *const RSA, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_RSAPrivateKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
|
||||
|
||||
pub fn RSA_sign(
|
||||
t: c_int,
|
||||
m: *const u8,
|
||||
mlen: c_uint,
|
||||
sig: *mut u8,
|
||||
siglen: *mut c_uint,
|
||||
k: *mut RSA,
|
||||
) -> c_int;
|
||||
pub fn RSA_verify(
|
||||
t: c_int,
|
||||
m: *const u8,
|
||||
mlen: c_uint,
|
||||
sig: *const u8,
|
||||
siglen: c_uint,
|
||||
k: *mut RSA,
|
||||
) -> c_int;
|
||||
|
||||
pub fn RSA_padding_check_PKCS1_type_2(
|
||||
to: *mut c_uchar,
|
||||
tlen: c_int,
|
||||
f: *const c_uchar,
|
||||
fl: c_int,
|
||||
rsa_len: c_int,
|
||||
) -> c_int;
|
||||
}
|
||||
1
openssl-sys/src/safestack.rs
Normal file
1
openssl-sys/src/safestack.rs
Normal file
@ -0,0 +1 @@
|
||||
stack!(stack_st_OPENSSL_STRING);
|
||||
70
openssl-sys/src/sha.rs
Normal file
70
openssl-sys/src/sha.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use libc::*;
|
||||
|
||||
pub type SHA_LONG = c_uint;
|
||||
|
||||
pub const SHA_LBLOCK: c_int = 16;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SHA_CTX {
|
||||
pub h0: SHA_LONG,
|
||||
pub h1: SHA_LONG,
|
||||
pub h2: SHA_LONG,
|
||||
pub h3: SHA_LONG,
|
||||
pub h4: SHA_LONG,
|
||||
pub Nl: SHA_LONG,
|
||||
pub Nh: SHA_LONG,
|
||||
pub data: [SHA_LONG; SHA_LBLOCK as usize],
|
||||
pub num: c_uint,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn SHA1_Init(c: *mut SHA_CTX) -> c_int;
|
||||
pub fn SHA1_Update(c: *mut SHA_CTX, data: *const c_void, len: size_t) -> c_int;
|
||||
pub fn SHA1_Final(md: *mut c_uchar, c: *mut SHA_CTX) -> c_int;
|
||||
pub fn SHA1(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SHA256_CTX {
|
||||
pub h: [SHA_LONG; 8],
|
||||
pub Nl: SHA_LONG,
|
||||
pub Nh: SHA_LONG,
|
||||
pub data: [SHA_LONG; SHA_LBLOCK as usize],
|
||||
pub num: c_uint,
|
||||
pub md_len: c_uint,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn SHA224_Init(c: *mut SHA256_CTX) -> c_int;
|
||||
pub fn SHA224_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int;
|
||||
pub fn SHA224_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int;
|
||||
pub fn SHA224(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
|
||||
pub fn SHA256_Init(c: *mut SHA256_CTX) -> c_int;
|
||||
pub fn SHA256_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int;
|
||||
pub fn SHA256_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int;
|
||||
pub fn SHA256(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
|
||||
}
|
||||
|
||||
pub type SHA_LONG64 = u64;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SHA512_CTX {
|
||||
pub h: [SHA_LONG64; 8],
|
||||
pub Nl: SHA_LONG64,
|
||||
pub Nh: SHA_LONG64,
|
||||
// this is a union but we don't want to require 1.19
|
||||
u: [SHA_LONG64; SHA_LBLOCK as usize],
|
||||
pub num: c_uint,
|
||||
pub md_len: c_uint,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn SHA384_Init(c: *mut SHA512_CTX) -> c_int;
|
||||
pub fn SHA384_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int;
|
||||
pub fn SHA384_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int;
|
||||
pub fn SHA384(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
|
||||
pub fn SHA512_Init(c: *mut SHA512_CTX) -> c_int;
|
||||
pub fn SHA512_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int;
|
||||
pub fn SHA512_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int;
|
||||
pub fn SHA512(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
|
||||
}
|
||||
18
openssl-sys/src/srtp.rs
Normal file
18
openssl-sys/src/srtp.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub const SRTP_AES128_CM_SHA1_80: c_ulong = 0x0001;
|
||||
pub const SRTP_AES128_CM_SHA1_32: c_ulong = 0x0002;
|
||||
pub const SRTP_AES128_F8_SHA1_80: c_ulong = 0x0003;
|
||||
pub const SRTP_AES128_F8_SHA1_32: c_ulong = 0x0004;
|
||||
pub const SRTP_NULL_SHA1_80: c_ulong = 0x0005;
|
||||
pub const SRTP_NULL_SHA1_32: c_ulong = 0x0006;
|
||||
|
||||
extern "C" {
|
||||
pub fn SSL_CTX_set_tlsext_use_srtp(ctx: *mut SSL_CTX, profiles: *const c_char) -> c_int;
|
||||
pub fn SSL_set_tlsext_use_srtp(ssl: *mut SSL, profiles: *const c_char) -> c_int;
|
||||
|
||||
pub fn SSL_get_srtp_profiles(ssl: *mut SSL) -> *mut stack_st_SRTP_PROTECTION_PROFILE;
|
||||
pub fn SSL_get_selected_srtp_profile(ssl: *mut SSL) -> *mut SRTP_PROTECTION_PROFILE;
|
||||
}
|
||||
1349
openssl-sys/src/ssl.rs
Normal file
1349
openssl-sys/src/ssl.rs
Normal file
File diff suppressed because it is too large
Load Diff
5
openssl-sys/src/ssl3.rs
Normal file
5
openssl-sys/src/ssl3.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use libc::*;
|
||||
|
||||
pub const SSL3_VERSION: c_int = 0x300;
|
||||
|
||||
pub const SSL3_AD_ILLEGAL_PARAMETER: c_int = 47;
|
||||
45
openssl-sys/src/stack.rs
Normal file
45
openssl-sys/src/stack.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use libc::*;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum OPENSSL_STACK {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct _STACK {
|
||||
pub num: c_int,
|
||||
pub data: *mut *mut c_char,
|
||||
pub sorted: c_int,
|
||||
pub num_alloc: c_int,
|
||||
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn OPENSSL_sk_num(stack: *const OPENSSL_STACK) -> c_int;
|
||||
pub fn OPENSSL_sk_value(stack: *const OPENSSL_STACK, idx: c_int) -> *mut c_void;
|
||||
|
||||
pub fn OPENSSL_sk_new_null() -> *mut OPENSSL_STACK;
|
||||
pub fn OPENSSL_sk_free(st: *mut OPENSSL_STACK);
|
||||
pub fn OPENSSL_sk_pop_free(
|
||||
st: *mut OPENSSL_STACK,
|
||||
free: Option<unsafe extern "C" fn(*mut c_void)>,
|
||||
);
|
||||
pub fn OPENSSL_sk_push(st: *mut OPENSSL_STACK, data: *const c_void) -> c_int;
|
||||
pub fn OPENSSL_sk_pop(st: *mut OPENSSL_STACK) -> *mut c_void;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn sk_num(st: *const _STACK) -> c_int;
|
||||
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
|
||||
|
||||
pub fn sk_new_null() -> *mut _STACK;
|
||||
pub fn sk_free(st: *mut _STACK);
|
||||
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
|
||||
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
|
||||
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
|
||||
}
|
||||
}
|
||||
}
|
||||
111
openssl-sys/src/tls1.rs
Normal file
111
openssl-sys/src/tls1.rs
Normal file
@ -0,0 +1,111 @@
|
||||
use libc::*;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use *;
|
||||
|
||||
pub const TLS1_VERSION: c_int = 0x301;
|
||||
pub const TLS1_1_VERSION: c_int = 0x302;
|
||||
pub const TLS1_2_VERSION: c_int = 0x303;
|
||||
#[cfg(ossl111)]
|
||||
pub const TLS1_3_VERSION: c_int = 0x304;
|
||||
|
||||
pub const TLS1_AD_DECODE_ERROR: c_int = 50;
|
||||
pub const TLS1_AD_UNRECOGNIZED_NAME: c_int = 112;
|
||||
|
||||
pub const TLSEXT_NAMETYPE_host_name: c_int = 0;
|
||||
pub const TLSEXT_STATUSTYPE_ocsp: c_int = 1;
|
||||
|
||||
extern "C" {
|
||||
pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char;
|
||||
|
||||
pub fn SSL_export_keying_material(
|
||||
s: *mut SSL,
|
||||
out: *mut c_uchar,
|
||||
olen: size_t,
|
||||
label: *const c_char,
|
||||
llen: size_t,
|
||||
context: *const c_uchar,
|
||||
contextlen: size_t,
|
||||
use_context: c_int,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn SSL_export_keying_material_early(
|
||||
s: *mut ::SSL,
|
||||
out: *mut c_uchar,
|
||||
olen: size_t,
|
||||
label: *const c_char,
|
||||
llen: size_t,
|
||||
context: *const c_uchar,
|
||||
contextlen: size_t,
|
||||
) -> c_int;
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_set_tlsext_host_name(s: *mut SSL, name: *mut c_char) -> c_long {
|
||||
SSL_ctrl(
|
||||
s,
|
||||
SSL_CTRL_SET_TLSEXT_HOSTNAME,
|
||||
TLSEXT_NAMETYPE_host_name as c_long,
|
||||
name as *mut c_void,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_set_tlsext_status_type(s: *mut SSL, type_: c_int) -> c_long {
|
||||
SSL_ctrl(
|
||||
s,
|
||||
SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,
|
||||
type_ as c_long,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_get_tlsext_status_ocsp_resp(ssl: *mut SSL, resp: *mut *mut c_uchar) -> c_long {
|
||||
SSL_ctrl(
|
||||
ssl,
|
||||
SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,
|
||||
0,
|
||||
resp as *mut c_void,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_set_tlsext_status_ocsp_resp(
|
||||
ssl: *mut SSL,
|
||||
resp: *mut c_uchar,
|
||||
len: c_long,
|
||||
) -> c_long {
|
||||
SSL_ctrl(
|
||||
ssl,
|
||||
SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,
|
||||
len,
|
||||
resp as *mut c_void,
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_tlsext_servername_callback(
|
||||
ctx: *mut SSL_CTX,
|
||||
// FIXME should have the right signature
|
||||
cb: Option<extern "C" fn()>,
|
||||
) -> c_long {
|
||||
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, cb)
|
||||
}
|
||||
|
||||
pub const SSL_TLSEXT_ERR_OK: c_int = 0;
|
||||
pub const SSL_TLSEXT_ERR_ALERT_WARNING: c_int = 1;
|
||||
pub const SSL_TLSEXT_ERR_ALERT_FATAL: c_int = 2;
|
||||
pub const SSL_TLSEXT_ERR_NOACK: c_int = 3;
|
||||
|
||||
pub unsafe fn SSL_CTX_set_tlsext_servername_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long {
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG, 0, arg)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_tlsext_status_cb(
|
||||
ctx: *mut SSL_CTX,
|
||||
cb: Option<unsafe extern "C" fn(*mut SSL, *mut c_void) -> c_int>,
|
||||
) -> c_long {
|
||||
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, mem::transmute(cb))
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_tlsext_status_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long {
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG, 0, arg)
|
||||
}
|
||||
349
openssl-sys/src/x509.rs
Normal file
349
openssl-sys/src/x509.rs
Normal file
@ -0,0 +1,349 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub const X509_FILETYPE_PEM: c_int = 1;
|
||||
pub const X509_FILETYPE_ASN1: c_int = 2;
|
||||
pub const X509_FILETYPE_DEFAULT: c_int = 3;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VAL {
|
||||
pub notBefore: *mut ASN1_TIME,
|
||||
pub notAfter: *mut ASN1_TIME,
|
||||
}
|
||||
|
||||
pub enum X509_NAME_ENTRY {}
|
||||
|
||||
stack!(stack_st_X509_NAME);
|
||||
|
||||
pub enum X509_EXTENSION {}
|
||||
|
||||
stack!(stack_st_X509_EXTENSION);
|
||||
|
||||
stack!(stack_st_X509_ATTRIBUTE);
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum X509_REQ_INFO {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ_INFO {
|
||||
pub enc: ASN1_ENCODING,
|
||||
pub version: *mut ::ASN1_INTEGER,
|
||||
pub subject: *mut ::X509_NAME,
|
||||
pubkey: *mut c_void,
|
||||
pub attributes: *mut stack_st_X509_ATTRIBUTE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum X509_REQ {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct X509_REQ {
|
||||
pub req_info: *mut X509_REQ_INFO,
|
||||
sig_alg: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
references: c_int,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub enum X509_CINF {}
|
||||
} else {
|
||||
#[repr(C)]
|
||||
pub struct X509_CINF {
|
||||
version: *mut c_void,
|
||||
serialNumber: *mut c_void,
|
||||
signature: *mut c_void,
|
||||
issuer: *mut c_void,
|
||||
pub validity: *mut X509_VAL,
|
||||
subject: *mut c_void,
|
||||
key: *mut c_void,
|
||||
issuerUID: *mut c_void,
|
||||
subjectUID: *mut c_void,
|
||||
pub extensions: *mut stack_st_X509_EXTENSION,
|
||||
enc: ASN1_ENCODING,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stack!(stack_st_X509);
|
||||
|
||||
extern "C" {
|
||||
pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char;
|
||||
|
||||
pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
|
||||
|
||||
pub fn X509_digest(
|
||||
x: *const X509,
|
||||
digest: *const EVP_MD,
|
||||
buf: *mut c_uchar,
|
||||
len: *mut c_uint,
|
||||
) -> c_int;
|
||||
|
||||
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
|
||||
|
||||
pub fn i2d_X509_bio(b: *mut BIO, x: *mut X509) -> c_int;
|
||||
pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int;
|
||||
pub fn i2d_PrivateKey_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int;
|
||||
pub fn i2d_PUBKEY_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn i2d_PUBKEY(k: *mut EVP_PKEY, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_PUBKEY(k: *mut *mut EVP_PKEY, buf: *mut *const u8, len: c_long) -> *mut EVP_PKEY;
|
||||
pub fn d2i_RSA_PUBKEY(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
|
||||
pub fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_DSA_PUBKEY(k: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
|
||||
pub fn i2d_DSA_PUBKEY(a: *mut DSA, pp: *mut *mut c_uchar) -> c_int;
|
||||
pub fn i2d_PrivateKey(k: *mut EVP_PKEY, buf: *mut *mut u8) -> c_int;
|
||||
|
||||
pub fn d2i_ECPrivateKey(
|
||||
k: *mut *mut EC_KEY,
|
||||
pp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut EC_KEY;
|
||||
pub fn i2d_ECPrivateKey(ec_key: *mut EC_KEY, pp: *mut *mut c_uchar) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn X509_ALGOR_get0(
|
||||
paobj: *mut *const ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
ppval: *mut *const c_void,
|
||||
alg: *const X509_ALGOR,
|
||||
);
|
||||
}
|
||||
} else if #[cfg(ossl102)] {
|
||||
extern "C" {
|
||||
pub fn X509_ALGOR_get0(
|
||||
paobj: *mut *mut ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
ppval: *mut *mut c_void,
|
||||
alg: *mut X509_ALGOR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME;
|
||||
|
||||
pub fn X509_to_X509_REQ(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> *mut X509_REQ;
|
||||
|
||||
pub fn X509_ALGOR_free(x: *mut X509_ALGOR);
|
||||
|
||||
pub fn X509_REQ_new() -> *mut X509_REQ;
|
||||
pub fn X509_REQ_free(x: *mut X509_REQ);
|
||||
pub fn d2i_X509_REQ(
|
||||
a: *mut *mut X509_REQ,
|
||||
pp: *mut *const c_uchar,
|
||||
length: c_long,
|
||||
) -> *mut X509_REQ;
|
||||
pub fn i2d_X509_REQ(x: *mut X509_REQ, buf: *mut *mut u8) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
extern "C" {
|
||||
pub fn X509_get0_signature(
|
||||
psig: *mut *const ASN1_BIT_STRING,
|
||||
palg: *mut *const X509_ALGOR,
|
||||
x: *const X509,
|
||||
);
|
||||
}
|
||||
} else if #[cfg(ossl102)] {
|
||||
extern "C" {
|
||||
pub fn X509_get0_signature(
|
||||
psig: *mut *mut ASN1_BIT_STRING,
|
||||
palg: *mut *mut X509_ALGOR,
|
||||
x: *const X509,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
#[cfg(ossl102)]
|
||||
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
|
||||
|
||||
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
|
||||
|
||||
pub fn X509_NAME_ENTRY_free(x: *mut X509_NAME_ENTRY);
|
||||
|
||||
pub fn X509_NAME_new() -> *mut X509_NAME;
|
||||
pub fn X509_NAME_free(x: *mut X509_NAME);
|
||||
|
||||
pub fn X509_new() -> *mut X509;
|
||||
pub fn X509_free(x: *mut X509);
|
||||
pub fn i2d_X509(x: *mut X509, buf: *mut *mut u8) -> c_int;
|
||||
pub fn d2i_X509(a: *mut *mut X509, pp: *mut *const c_uchar, length: c_long) -> *mut X509;
|
||||
|
||||
pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn X509_set_version(x: *mut X509, version: c_long) -> c_int;
|
||||
pub fn X509_set_serialNumber(x: *mut X509, sn: *mut ASN1_INTEGER) -> c_int;
|
||||
pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER;
|
||||
pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509_get_issuer_name(x: *const ::X509) -> *mut ::X509_NAME;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
pub fn X509_set_subject_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
#[cfg(ossl110)]
|
||||
pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long;
|
||||
pub fn X509_REQ_set_version(req: *mut X509_REQ, version: c_long) -> c_int;
|
||||
#[cfg(ossl110)]
|
||||
pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut X509_NAME;
|
||||
pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut X509_NAME) -> c_int;
|
||||
pub fn X509_REQ_set_pubkey(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
|
||||
pub fn X509_REQ_get_pubkey(req: *mut X509_REQ) -> *mut EVP_PKEY;
|
||||
pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION;
|
||||
pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION)
|
||||
-> c_int;
|
||||
pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
|
||||
pub fn X509_REQ_verify(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn X509_getm_notBefore(x: *const X509) -> *mut ASN1_TIME;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn X509_getm_notAfter(x: *const X509) -> *mut ASN1_TIME;
|
||||
#[cfg(any(ossl110, libressl273))]
|
||||
pub fn X509_up_ref(x: *mut X509) -> c_int;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_entry_count(n: *const X509_NAME) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_entry_count(n: *mut X509_NAME) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(libressl280)] {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_get_index_by_NID(n: *const X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_get_entry(n: *const X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY;
|
||||
pub fn X509_NAME_add_entry_by_NID(
|
||||
x: *mut X509_NAME,
|
||||
field: c_int,
|
||||
ty: c_int,
|
||||
bytes: *const c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
pub fn X509_NAME_ENTRY_get_object(ne: *const X509_NAME_ENTRY) -> *mut ASN1_OBJECT;
|
||||
pub fn X509_NAME_ENTRY_get_data(ne: *const X509_NAME_ENTRY) -> *mut ASN1_STRING;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_NAME_get_entry(n: *mut X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY;
|
||||
pub fn X509_NAME_add_entry_by_NID(
|
||||
x: *mut X509_NAME,
|
||||
field: c_int,
|
||||
ty: c_int,
|
||||
bytes: *mut c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
pub fn X509_NAME_ENTRY_get_object(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_OBJECT;
|
||||
pub fn X509_NAME_ENTRY_get_data(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_STRING;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
pub fn X509_NAME_add_entry_by_txt(
|
||||
x: *mut X509_NAME,
|
||||
field: *const c_char,
|
||||
ty: c_int,
|
||||
bytes: *const c_uchar,
|
||||
len: c_int,
|
||||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509_get_ext_d2i(
|
||||
x: *const ::X509,
|
||||
nid: c_int,
|
||||
crit: *mut c_int,
|
||||
idx: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_get_ext_d2i(
|
||||
x: *mut ::X509,
|
||||
nid: c_int,
|
||||
crit: *mut c_int,
|
||||
idx: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int;
|
||||
}
|
||||
153
openssl-sys/src/x509_vfy.rs
Normal file
153
openssl-sys/src/x509_vfy.rs
Normal file
@ -0,0 +1,153 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
#[cfg(any(libressl, all(ossl102, not(ossl110))))]
|
||||
pub enum X509_VERIFY_PARAM_ID {}
|
||||
|
||||
pub const X509_V_OK: c_int = 0;
|
||||
#[cfg(ossl102f)]
|
||||
pub const X509_V_ERR_UNSPECIFIED: c_int = 1;
|
||||
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2;
|
||||
pub const X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3;
|
||||
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4;
|
||||
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5;
|
||||
pub const X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6;
|
||||
pub const X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7;
|
||||
pub const X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8;
|
||||
pub const X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9;
|
||||
pub const X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10;
|
||||
pub const X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11;
|
||||
pub const X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12;
|
||||
pub const X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13;
|
||||
pub const X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14;
|
||||
pub const X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15;
|
||||
pub const X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16;
|
||||
pub const X509_V_ERR_OUT_OF_MEM: c_int = 17;
|
||||
pub const X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18;
|
||||
pub const X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19;
|
||||
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20;
|
||||
pub const X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21;
|
||||
pub const X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22;
|
||||
pub const X509_V_ERR_CERT_REVOKED: c_int = 23;
|
||||
pub const X509_V_ERR_INVALID_CA: c_int = 24;
|
||||
pub const X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25;
|
||||
pub const X509_V_ERR_INVALID_PURPOSE: c_int = 26;
|
||||
pub const X509_V_ERR_CERT_UNTRUSTED: c_int = 27;
|
||||
pub const X509_V_ERR_CERT_REJECTED: c_int = 28;
|
||||
pub const X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29;
|
||||
pub const X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30;
|
||||
pub const X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31;
|
||||
pub const X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32;
|
||||
pub const X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33;
|
||||
pub const X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34;
|
||||
pub const X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35;
|
||||
pub const X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36;
|
||||
pub const X509_V_ERR_INVALID_NON_CA: c_int = 37;
|
||||
pub const X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38;
|
||||
pub const X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39;
|
||||
pub const X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40;
|
||||
pub const X509_V_ERR_INVALID_EXTENSION: c_int = 41;
|
||||
pub const X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42;
|
||||
pub const X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43;
|
||||
pub const X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44;
|
||||
pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
|
||||
pub const X509_V_ERR_UNNESTED_RESOURCE: c_int = 46;
|
||||
pub const X509_V_ERR_PERMITTED_VIOLATION: c_int = 47;
|
||||
pub const X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48;
|
||||
pub const X509_V_ERR_SUBTREE_MINMAX: c_int = 49;
|
||||
pub const X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50;
|
||||
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51;
|
||||
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52;
|
||||
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
|
||||
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63;
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64;
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
pub const X509_V_ERR_DANE_NO_MATCH: c_int = 65;
|
||||
pub const X509_V_ERR_EE_KEY_TOO_SMALL: c_int = 66;
|
||||
pub const X509_V_ERR_CA_KEY_TOO_SMALL: c_int = 67;
|
||||
pub const X509_V_ERR_CA_MD_TOO_WEAK: c_int = 68;
|
||||
pub const X509_V_ERR_INVALID_CALL: c_int = 69;
|
||||
pub const X509_V_ERR_STORE_LOOKUP: c_int = 70;
|
||||
pub const X509_V_ERR_NO_VALID_SCTS: c_int = 71;
|
||||
} else if #[cfg(ossl102h)] {
|
||||
pub const X509_V_ERR_INVALID_CALL: c_int = 65;
|
||||
pub const X509_V_ERR_STORE_LOOKUP: c_int = 66;
|
||||
pub const X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: c_int = 67;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn X509_STORE_new() -> *mut X509_STORE;
|
||||
pub fn X509_STORE_free(store: *mut X509_STORE);
|
||||
|
||||
pub fn X509_STORE_CTX_new() -> *mut X509_STORE_CTX;
|
||||
|
||||
pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX);
|
||||
pub fn X509_STORE_CTX_init(
|
||||
ctx: *mut X509_STORE_CTX,
|
||||
store: *mut X509_STORE,
|
||||
x509: *mut X509,
|
||||
chain: *mut stack_st_X509,
|
||||
) -> c_int;
|
||||
pub fn X509_STORE_CTX_cleanup(ctx: *mut X509_STORE_CTX);
|
||||
|
||||
pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int;
|
||||
|
||||
pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int;
|
||||
|
||||
pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
|
||||
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
|
||||
pub fn X509_STORE_CTX_set_error(ctx: *mut X509_STORE_CTX, error: c_int);
|
||||
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;
|
||||
pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
extern "C" {
|
||||
pub fn X509_STORE_CTX_get0_chain(ctx: *mut X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509_STORE_CTX_get_chain(ctx: *mut X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
|
||||
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set1_host(
|
||||
param: *mut X509_VERIFY_PARAM,
|
||||
name: *const c_char,
|
||||
namelen: size_t,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint);
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set1_ip(
|
||||
param: *mut X509_VERIFY_PARAM,
|
||||
ip: *const c_uchar,
|
||||
iplen: size_t,
|
||||
) -> c_int;
|
||||
}
|
||||
93
openssl-sys/src/x509v3.rs
Normal file
93
openssl-sys/src/x509v3.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use libc::*;
|
||||
|
||||
use *;
|
||||
|
||||
pub enum CONF_METHOD {}
|
||||
|
||||
pub const GEN_OTHERNAME: c_int = 0;
|
||||
pub const GEN_EMAIL: c_int = 1;
|
||||
pub const GEN_DNS: c_int = 2;
|
||||
pub const GEN_X400: c_int = 3;
|
||||
pub const GEN_DIRNAME: c_int = 4;
|
||||
pub const GEN_EDIPARTY: c_int = 5;
|
||||
pub const GEN_URI: c_int = 6;
|
||||
pub const GEN_IPADD: c_int = 7;
|
||||
pub const GEN_RID: c_int = 8;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct GENERAL_NAME {
|
||||
pub type_: c_int,
|
||||
// FIXME should be a union
|
||||
pub d: *mut c_void,
|
||||
}
|
||||
|
||||
stack!(stack_st_GENERAL_NAME);
|
||||
|
||||
extern "C" {
|
||||
pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME);
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10;
|
||||
#[cfg(ossl110)]
|
||||
pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn X509V3_EXT_nconf_nid(
|
||||
conf: *mut CONF,
|
||||
ctx: *mut X509V3_CTX,
|
||||
ext_nid: c_int,
|
||||
value: *const c_char,
|
||||
) -> *mut X509_EXTENSION;
|
||||
pub fn X509V3_EXT_nconf(
|
||||
conf: *mut CONF,
|
||||
ctx: *mut X509V3_CTX,
|
||||
name: *const c_char,
|
||||
value: *const c_char,
|
||||
) -> *mut X509_EXTENSION;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn X509V3_EXT_nconf_nid(
|
||||
conf: *mut CONF,
|
||||
ctx: *mut X509V3_CTX,
|
||||
ext_nid: c_int,
|
||||
value: *mut c_char,
|
||||
) -> *mut X509_EXTENSION;
|
||||
pub fn X509V3_EXT_nconf(
|
||||
conf: *mut CONF,
|
||||
ctx: *mut X509V3_CTX,
|
||||
name: *mut c_char,
|
||||
value: *mut c_char,
|
||||
) -> *mut X509_EXTENSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> c_int;
|
||||
pub fn X509_verify(req: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
|
||||
|
||||
pub fn X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF);
|
||||
|
||||
pub fn X509V3_set_ctx(
|
||||
ctx: *mut X509V3_CTX,
|
||||
issuer: *mut X509,
|
||||
subject: *mut X509,
|
||||
req: *mut X509_REQ,
|
||||
crl: *mut X509_CRL,
|
||||
flags: c_int,
|
||||
);
|
||||
|
||||
pub fn X509_get1_ocsp(x: *mut X509) -> *mut stack_st_OPENSSL_STRING;
|
||||
}
|
||||
427
openssl/CHANGELOG.md
Normal file
427
openssl/CHANGELOG.md
Normal file
@ -0,0 +1,427 @@
|
||||
# Change Log
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.10.25] - 2019-10-02
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a memory leak in `EcdsaSig::from_private_components` when using OpenSSL 1.0.x.
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for Ed25519 and Ed448 keys.
|
||||
* Implemented `ToOwned` for `PKeyRef` and `Clone` for `PKey`.
|
||||
|
||||
## [v0.10.24] - 2019-07-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* Worked around an OpenSSL 1.0.x bug triggered by code calling `SSL_set_app_data`.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `aes::{wrap_key, unwrap_key}`.
|
||||
* Added `CmsContentInfoRef::to_pem` and `CmsContentInfo::from_pem`.
|
||||
* Added `DsaRef::private_key_to_pem`.
|
||||
* Added `EcGroupRef::{cofactor, generator}`.
|
||||
* Added `EcPointRef::to_owned`.
|
||||
* Added a `Debug` implementation for `EcKey`.
|
||||
* Added `SslAcceptor::{mozilla_intermediate_v5, mozilla_modern_v5}`.
|
||||
* Added `Cipher::{aes_128_ofb, aes_192_ecb, aes_192_cbc, aes_192_ctr, aes_192_cfb1, aes_192_cfb128, aes_192_cfb8,
|
||||
aes_192_gcm, aes_192_ccm, aes_192_ofb, aes_256_ofb}`.
|
||||
|
||||
## [v0.10.23] - 2019-05-18
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed session callbacks when an `Ssl`'s context is replaced.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslContextBuilder::add_client_ca`.
|
||||
|
||||
## [v0.10.22] - 2019-05-08
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for the LibreSSL 2.9.x series.
|
||||
|
||||
## [v0.10.21] - 2019-04-30
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed overly conservatifve buffer size checks in `Crypter` when using stream ciphers.
|
||||
|
||||
### Added
|
||||
|
||||
* Added bindings to envelope encryption APIs.
|
||||
* Added `PkeyRef::size`.
|
||||
|
||||
## [v0.10.20] - 2019-03-20
|
||||
|
||||
### Added
|
||||
|
||||
* Added `CmsContentInfo::from_der` and `CmsContentInfo::encrypt`.
|
||||
* Added `X509Ref::verify` and `X509ReqRef::verify`.
|
||||
* Implemented `PartialEq` and `Eq` for `MessageDigest`.
|
||||
* Added `MessageDigest::type_` and `EcGroupRef::curve_name`.
|
||||
|
||||
## [v0.10.19] - 2019-03-01
|
||||
|
||||
### Added
|
||||
|
||||
* The openssl-sys build script now logs the values of environment variables.
|
||||
* Added `ERR_PACK` to openssl-sys.
|
||||
* The `ERR_*` functions in openssl-sys are const functions when building against newer Rust versions.
|
||||
* Implemented `Clone` for `Dsa`.
|
||||
* Added `SslContextRef::add_session` and `SslContextRef::remove_session`.
|
||||
* Added `SslSessionRef::time`, `SslSessionRef::timeout`, and `SslSessionRef::protocol_version`.
|
||||
* Added `SslContextBuilder::set_session_cache_size` and `SslContextRef::session_cache_size`.
|
||||
|
||||
## [v0.10.18] - 2019-02-22
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed the return type of `ssl::cipher_name`.
|
||||
|
||||
## [v0.10.17] - 2019-02-22
|
||||
|
||||
### Added
|
||||
|
||||
* Implemented `AsRef<str>` and `AsRef<[u8]>` for `OpenSslString`.
|
||||
* Added `Asn1Integer::from_bn`.
|
||||
* Added `RsaRef::check_key`.
|
||||
* Added `Asn1Time::from_str` and `Asn1Time::from_str_x509`.
|
||||
* Added `Rsa::generate_with_e`.
|
||||
* Added `Cipher::des_ede3_cfb64`.
|
||||
* Added `SslCipherRef::standard_name` and `ssl::cipher_name`.
|
||||
|
||||
## [v0.10.16] - 2018-12-16
|
||||
|
||||
### Added
|
||||
|
||||
* Added SHA3 and SHAKE to `MessageDigest`.
|
||||
* Added `rand::keep_random_devices_open`.
|
||||
* Added support for LibreSSL 2.9.0.
|
||||
|
||||
## [v0.10.15] - 2018-10-22
|
||||
|
||||
### Added
|
||||
|
||||
* Implemented `DoubleEndedIterator` for stack iterators.
|
||||
|
||||
## [v0.10.14] - 2018-10-18
|
||||
|
||||
### Fixed
|
||||
|
||||
* Made some accidentally exposed internal functions private.
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for LibreSSL 2.8.
|
||||
|
||||
### Changed
|
||||
|
||||
* The OpenSSL version used with the `vendored` feature has been upgraded from 1.1.0 to 1.1.1.
|
||||
|
||||
## [v0.10.13] - 2018-10-14
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a double-free in the `SslContextBuilder::set_get_session_callback` API.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslContextBuilder::set_client_hello_callback`.
|
||||
* Added support for LibreSSL 2.8.1.
|
||||
* Added `EcdsaSig::from_der` and `EcdsaSig::to_der`.
|
||||
* Added PKCS#7 support.
|
||||
|
||||
## [v0.10.12] - 2018-09-13
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed handling of SNI callbacks during renegotiation.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslRef::get_shutdown` and `SslRef::set_shutdown`.
|
||||
* Added support for SRTP in DTLS sessions.
|
||||
* Added support for LibreSSL 2.8.0.
|
||||
|
||||
## [v0.10.11] - 2018-08-04
|
||||
|
||||
### Added
|
||||
|
||||
* The new `vendored` cargo feature will cause openssl-sys to compile and statically link to a
|
||||
vendored copy of OpenSSL.
|
||||
* Added `SslContextBuilder::set_psk_server_callback`.
|
||||
* Added `DsaRef::pub_key` and `DsaRef::priv_key`.
|
||||
* Added `Dsa::from_private_components` and `Dsa::from_public_components`.
|
||||
* Added `X509NameRef::entries`.
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `SslContextBuilder::set_psk_callback` has been renamed to
|
||||
`SslContextBuilder::set_psk_client_callback` and deprecated.
|
||||
|
||||
## [v0.10.10] - 2018-06-06
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslRef::set_alpn_protos`.
|
||||
* Added `SslContextBuilder::set_ciphersuites`.
|
||||
|
||||
## [v0.10.9] - 2018-06-01
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a use-after-free in `CmsContentInfo::sign`.
|
||||
* `SslRef::servername` now returns `None` rather than panicking on a non-UTF8 name.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `MessageDigest::from_nid`.
|
||||
* Added `Nid::signature_algorithms`, `Nid::long_name`, and `Nid::short_name`.
|
||||
* Added early data and early keying material export support for TLS 1.3.
|
||||
* Added `SslRef::verified_chain`.
|
||||
* Added `SslRef::servername_raw` which returns a `&[u8]` rather than `&str`.
|
||||
* Added `SslRef::finished` and `SslRef::peer_finished`.
|
||||
* Added `X509Ref::digest` to replace `X509Ref::fingerprint`.
|
||||
* `X509StoreBuilder` and `X509Store` now implement `Sync` and `Send`.
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `X509Ref::fingerprint` has been deprecated in favor of `X509Ref::digest`.
|
||||
|
||||
## [v0.10.8] - 2018-05-20
|
||||
|
||||
### Fixed
|
||||
|
||||
* `openssl-sys` will now detect Homebrew-installed OpenSSL when installed to a non-default
|
||||
directory.
|
||||
* The `X509_V_ERR_INVALID_CALL`, `X509_V_ERR_STORE_LOOKUP`, and
|
||||
`X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION` constants in `openssl-sys` are now only present when
|
||||
building against 1.1.0g and up rather than 1.1.0.
|
||||
* `SslContextBuilder::max_proto_version` and `SslContextBuilder::min_proto_version` are only present
|
||||
when building against 1.1.0g and up rather than 1.1.0.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `CmsContentInfo::sign`.
|
||||
* Added `Clone` and `ToOwned` implementations to `Rsa` and `RsaRef` respectively.
|
||||
* The `min_proto_version` and `max_proto_version` methods are available when linking against
|
||||
LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* `X509VerifyParam` is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* ALPN support is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* `Stack` and `StackRef` are now `Sync` and `Send`.
|
||||
|
||||
## [v0.10.7] - 2018-04-30
|
||||
|
||||
### Added
|
||||
|
||||
* Added `X509Req::public_key` and `X509Req::extensions`.
|
||||
* Added `RsaPrivateKeyBuilder` to allow control over initialization of optional components of an RSA
|
||||
private key.
|
||||
* Added DER encode/decode support to `SslSession`.
|
||||
* openssl-sys now provides the `DEP_OPENSSL_VERSION_NUMBER` and
|
||||
`DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` environment variables to downstream build scripts which
|
||||
contains the hex-encoded version number of the OpenSSL or LibreSSL distribution being built
|
||||
against. The other variables are deprecated.
|
||||
|
||||
## [v0.10.6] - 2018-03-05
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslOptions::ENABLE_MIDDLEBOX_COMPAT`.
|
||||
* Added more `Sync` and `Send` implementations.
|
||||
* Added `PKeyRef::id`.
|
||||
* Added `Padding::PKCS1_PSS`.
|
||||
* Added `Signer::set_rsa_pss_saltlen`, `Signer::set_rsa_mgf1_md`, `Signer::set_rsa_pss_saltlen`, and
|
||||
`Signer::set_rsa_mgf1_md`
|
||||
* Added `X509StoreContextRef::verify` to directly verify certificates.
|
||||
* Added low level ECDSA support.
|
||||
* Added support for TLSv1.3 custom extensions. (OpenSSL 1.1.1 only)
|
||||
* Added AES-CCM support.
|
||||
* Added `EcKey::from_private_components`.
|
||||
* Added CMAC support.
|
||||
* Added support for LibreSSL 2.7.
|
||||
* Added `X509Ref::serial_number`.
|
||||
* Added `Asn1IntegerRef::to_bn`.
|
||||
* Added support for TLSv1.3 stateless handshakes. (OpenSSL 1.1.1 only)
|
||||
|
||||
### Changed
|
||||
|
||||
* The Cargo features previously used to gate access to version-specific OpenSSL APIs have been
|
||||
removed. Those APIs will be available automatically when building against an appropriate OpenSSL
|
||||
version.
|
||||
* Fixed `PKey::private_key_from_der` to return a `PKey<Private>` rather than a `PKey<Public>`. This
|
||||
is technically a breaking change but the function was pretty useless previously.
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `X509CheckFlags::FLAG_NO_WILDCARDS` has been renamed to `X509CheckFlags::NO_WILDCARDS` and the old
|
||||
name deprecated.
|
||||
|
||||
## [v0.10.5] - 2018-02-28
|
||||
|
||||
### Fixed
|
||||
|
||||
* `ErrorStack`'s `Display` implementation no longer writes an empty string if it contains no errors.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `SslRef::version2`.
|
||||
* Added `Cipher::des_ede3_cbc`.
|
||||
* Added `SslRef::export_keying_material`.
|
||||
* Added the ability to push an `Error` or `ErrorStack` back onto OpenSSL's error stack. Various
|
||||
callback bindings use this to propagate errors properly.
|
||||
* Added `SslContextBuilder::set_cookie_generate_cb` and `SslContextBuilder::set_cookie_verify_cb`.
|
||||
* Added `SslContextBuilder::set_max_proto_version`, `SslContextBuilder::set_min_proto_version`,
|
||||
`SslContextBuilder::max_proto_version`, and `SslContextBuilder::min_proto_version`.
|
||||
|
||||
### Changed
|
||||
|
||||
* Updated `SslConnector`'s default cipher list to match Python's.
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `SslRef::version` has been deprecated. Use `SslRef::version_str` instead.
|
||||
|
||||
## [v0.10.4] - 2018-02-18
|
||||
|
||||
### Added
|
||||
|
||||
* Added OpenSSL 1.1.1 support.
|
||||
* Added `Rsa::public_key_from_pem_pkcs1`.
|
||||
* Added `SslOptions::NO_TLSV1_3`. (OpenSSL 1.1.1 only)
|
||||
* Added `SslVersion`.
|
||||
* Added `SslSessionCacheMode` and `SslContextBuilder::set_session_cache_mode`.
|
||||
* Added `SslContextBuilder::set_new_session_callback`,
|
||||
`SslContextBuilder::set_remove_session_callback`, and
|
||||
`SslContextBuilder::set_get_session_callback`.
|
||||
* Added `SslContextBuilder::set_keylog_callback`. (OpenSSL 1.1.1 only)
|
||||
* Added `SslRef::client_random` and `SslRef::server_random`. (OpenSSL 1.1.0+ only)
|
||||
|
||||
### Fixed
|
||||
|
||||
* The `SslAcceptorBuilder::mozilla_modern` constructor now disables TLSv1.0 and TLSv1.1 in
|
||||
accordance with Mozilla's recommendations.
|
||||
|
||||
## [v0.10.3] - 2018-02-12
|
||||
|
||||
### Added
|
||||
|
||||
* OpenSSL is now automatically detected on FreeBSD systems.
|
||||
* Added `GeneralName` accessors for `rfc822Name` and `uri` variants.
|
||||
* Added DES-EDE3 support.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a memory leak in `X509StoreBuilder::add_cert`.
|
||||
|
||||
## [v0.10.2] - 2018-01-11
|
||||
|
||||
### Added
|
||||
|
||||
* Added `ConnectConfiguration::set_use_server_name_indication` and
|
||||
`ConnectConfiguration::set_verify_hostname` for use in contexts where you don't have ownership
|
||||
of the `ConnectConfiguration`.
|
||||
|
||||
## [v0.10.1] - 2018-01-10
|
||||
|
||||
### Added
|
||||
|
||||
* Added a `From<ErrorStack> for ssl::Error` implementation.
|
||||
|
||||
## [v0.10.0] - 2018-01-10
|
||||
|
||||
### Compatibility
|
||||
|
||||
* openssl 0.10 still uses openssl-sys 0.9, so openssl 0.9 and 0.10 can coexist without issue.
|
||||
|
||||
### Added
|
||||
|
||||
* The `ssl::select_next_proto` function can be used to easily implement the ALPN selection callback
|
||||
in a "standard" way.
|
||||
* FIPS mode support is available in the `fips` module.
|
||||
* Accessors for the Issuer and Issuer Alternative Name fields of X509 certificates have been added.
|
||||
* The `X509VerifyResult` can now be set in the certificate verification callback via
|
||||
`X509StoreContextRef::set_error`.
|
||||
|
||||
### Changed
|
||||
|
||||
* All constants have been moved to associated constants of their type. For example, `bn::MSB_ONE`
|
||||
is now `bn::MsbOption::ONE`.
|
||||
* Asymmetric key types are now parameterized over what they contain. In OpenSSL, the same type is
|
||||
used for key parameters, public keys, and private keys. Unfortunately, some APIs simply assume
|
||||
that certain components are present and will segfault trying to use things that aren't there.
|
||||
|
||||
The `pkey` module contains new tag types named `Params`, `Public`, and `Private`, and the
|
||||
`Dh`, `Dsa`, `EcKey`, `Rsa`, and `PKey` have a type parameter set to one of those values. This
|
||||
allows the `Signer` constructor to indicate that it requires a private key at compile time for
|
||||
example. Previously, `Signer` would simply segfault if provided a key without private
|
||||
components.
|
||||
* ALPN support has been changed to more directly model OpenSSL's own APIs. Instead of a single
|
||||
method used for both the server and client sides which performed everything automatically, the
|
||||
`SslContextBuilder::set_alpn_protos` and `SslContextBuilder::set_alpn_select_callback` handle
|
||||
the client and server sides respectively.
|
||||
* `SslConnector::danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication`
|
||||
has been removed in favor of new methods which provide more control. The
|
||||
`ConnectConfiguration::use_server_name_indication` method controls the use of Server Name
|
||||
Indication (SNI), and the `ConnectConfiguration::verify_hostname` method controls the use of
|
||||
hostname verification. These can be controlled independently, and if both are disabled, the
|
||||
domain argument to `ConnectConfiguration::connect` is ignored.
|
||||
* Shared secret derivation is now handled by the new `derive::Deriver` type rather than
|
||||
`pkey::PKeyContext`, which has been removed.
|
||||
* `ssl::Error` is now no longer an enum, and provides more direct access to the relevant state.
|
||||
* `SslConnectorBuilder::new` has been moved and renamed to `SslConnector::builder`.
|
||||
* `SslAcceptorBuilder::mozilla_intermediate` and `SslAcceptorBuilder::mozilla_modern` have been
|
||||
moved to `SslAcceptor` and no longer take the private key and certificate chain. Install those
|
||||
manually after creating the builder.
|
||||
* `X509VerifyError` is now `X509VerifyResult` and can now have the "ok" value in addition to error
|
||||
values.
|
||||
* `x509::X509FileType` is now `ssl::SslFiletype`.
|
||||
* Asymmetric key serialization and deserialization methods now document the formats that they
|
||||
correspond to, and some have been renamed to better indicate that.
|
||||
|
||||
### Removed
|
||||
|
||||
* All deprecated APIs have been removed.
|
||||
* NPN support has been removed. It has been supersceded by ALPN, and is hopefully no longer being
|
||||
used in practice. If you still depend on it, please file an issue!
|
||||
* `SslRef::compression` has been removed.
|
||||
* Some `ssl::SslOptions` flags have been removed as they no longer do anything.
|
||||
|
||||
## Older
|
||||
|
||||
Look at the [release tags] for information about older releases.
|
||||
|
||||
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.24...master
|
||||
[v0.10.24]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.23...openssl-v0.10.24
|
||||
[v0.10.23]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.22...openssl-v0.10.23
|
||||
[v0.10.22]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.21...openssl-v0.10.22
|
||||
[v0.10.21]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.20...openssl-v0.10.21
|
||||
[v0.10.20]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.19...openssl-v0.10.20
|
||||
[v0.10.19]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.18...openssl-v0.10.19
|
||||
[v0.10.18]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.17...openssl-v0.10.18
|
||||
[v0.10.17]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.16...openssl-v0.10.17
|
||||
[v0.10.16]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.15...openssl-v0.10.16
|
||||
[v0.10.15]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.14...openssl-v0.10.15
|
||||
[v0.10.14]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.13...openssl-v0.10.14
|
||||
[v0.10.13]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.12...openssl-v0.10.13
|
||||
[v0.10.12]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.11...openssl-v0.10.12
|
||||
[v0.10.11]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.10...openssl-v0.10.11
|
||||
[v0.10.10]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.9...openssl-v0.10.10
|
||||
[v0.10.9]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.8...openssl-v0.10.9
|
||||
[v0.10.8]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...openssl-v0.10.8
|
||||
[v0.10.7]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.6...openssl-v0.10.7
|
||||
[v0.10.6]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.5...openssl-v0.10.6
|
||||
[v0.10.5]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.4...openssl-v0.10.5
|
||||
[v0.10.4]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.3...openssl-v0.10.4
|
||||
[v0.10.3]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.2...openssl-v0.10.3
|
||||
[v0.10.2]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.1...openssl-v0.10.2
|
||||
[v0.10.1]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.0...openssl-v0.10.1
|
||||
[v0.10.0]: https://github.com/sfackler/rust-openssl/compare/v0.9.23...openssl-v0.10.0
|
||||
[release tags]: https://github.com/sfackler/rust-openssl/releases
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "openssl"
|
||||
version = "0.9.24"
|
||||
version = "0.10.25"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "Apache-2.0"
|
||||
description = "OpenSSL bindings"
|
||||
@ -8,26 +8,25 @@ repository = "https://github.com/sfackler/rust-openssl"
|
||||
readme = "README.md"
|
||||
keywords = ["crypto", "tls", "ssl", "dtls"]
|
||||
categories = ["cryptography", "api-bindings"]
|
||||
build = "build.rs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
# these are deprecated and don't do anything anymore
|
||||
[features]
|
||||
v101 = []
|
||||
v102 = []
|
||||
v110 = []
|
||||
v111 = []
|
||||
|
||||
vendored = ['openssl-sys/vendored']
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.9"
|
||||
bitflags = "1.0"
|
||||
cfg-if = "0.1"
|
||||
foreign-types = "0.3.1"
|
||||
lazy_static = "1"
|
||||
libc = "0.2"
|
||||
openssl-sys = { version = "0.9.23", path = "../openssl-sys" }
|
||||
|
||||
openssl-sys = { version = "0.9.50", path = "../openssl-sys" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
winapi = "0.2"
|
||||
ws2_32-sys = "0.2"
|
||||
hex = "0.2"
|
||||
data-encoding = "2.0"
|
||||
hex = "0.3"
|
||||
|
||||
@ -1,21 +1,6 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
match env::var("DEP_OPENSSL_VERSION") {
|
||||
Ok(ref v) if v == "101" => {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
println!("cargo:rustc-cfg=ossl10x");
|
||||
}
|
||||
Ok(ref v) if v == "102" => {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:rustc-cfg=ossl10x");
|
||||
}
|
||||
Ok(ref v) if v == "110" => {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
}
|
||||
_ => panic!("Unable to detect OpenSSL version"),
|
||||
}
|
||||
|
||||
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
}
|
||||
@ -29,4 +14,52 @@ fn main() {
|
||||
println!("cargo:rustc-cfg=osslconf=\"{}\"", var);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
|
||||
let version = u64::from_str_radix(&version, 16).unwrap();
|
||||
|
||||
if version >= 0x1_00_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
}
|
||||
if version >= 0x1_00_02_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
}
|
||||
if version >= 0x1_01_00_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
}
|
||||
if version >= 0x1_01_00_07_0 {
|
||||
println!("cargo:rustc-cfg=ossl110g");
|
||||
}
|
||||
if version >= 0x1_01_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl111");
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
|
||||
let version = u64::from_str_radix(&version, 16).unwrap();
|
||||
|
||||
if version >= 0x2_06_01_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl261");
|
||||
}
|
||||
|
||||
if version >= 0x2_07_00_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl270");
|
||||
}
|
||||
|
||||
if version >= 0x2_07_01_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl271");
|
||||
}
|
||||
|
||||
if version >= 0x2_07_03_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl273");
|
||||
}
|
||||
|
||||
if version >= 0x2_08_00_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl280");
|
||||
}
|
||||
|
||||
if version >= 0x2_09_01_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl291");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,18 +4,19 @@
|
||||
extern crate openssl;
|
||||
|
||||
use openssl::asn1::Asn1Time;
|
||||
use openssl::bn::{BigNum, MSB_MAYBE_ZERO};
|
||||
use openssl::bn::{BigNum, MsbOption};
|
||||
use openssl::error::ErrorStack;
|
||||
use openssl::hash::MessageDigest;
|
||||
use openssl::pkey::{PKey, PKeyRef};
|
||||
use openssl::pkey::{PKey, PKeyRef, Private};
|
||||
use openssl::rsa::Rsa;
|
||||
use openssl::x509::{X509, X509Ref};
|
||||
use openssl::x509::{X509NameBuilder, X509Req, X509ReqBuilder};
|
||||
use openssl::x509::extension::{AuthorityKeyIdentifier, BasicConstraints, KeyUsage,
|
||||
SubjectAlternativeName, SubjectKeyIdentifier};
|
||||
use openssl::x509::extension::{
|
||||
AuthorityKeyIdentifier, BasicConstraints, KeyUsage, SubjectAlternativeName,
|
||||
SubjectKeyIdentifier,
|
||||
};
|
||||
use openssl::x509::{X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult, X509};
|
||||
|
||||
/// Make a CA certificate and private key
|
||||
fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> {
|
||||
fn mk_ca_cert() -> Result<(X509, PKey<Private>), ErrorStack> {
|
||||
let rsa = Rsa::generate(2048)?;
|
||||
let privkey = PKey::from_rsa(rsa)?;
|
||||
|
||||
@ -30,7 +31,7 @@ fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> {
|
||||
cert_builder.set_version(2)?;
|
||||
let serial_number = {
|
||||
let mut serial = BigNum::new()?;
|
||||
serial.rand(159, MSB_MAYBE_ZERO, false)?;
|
||||
serial.rand(159, MsbOption::MAYBE_ZERO, false)?;
|
||||
serial.to_asn1_integer()?
|
||||
};
|
||||
cert_builder.set_serial_number(&serial_number)?;
|
||||
@ -43,11 +44,13 @@ fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> {
|
||||
cert_builder.set_not_after(¬_after)?;
|
||||
|
||||
cert_builder.append_extension(BasicConstraints::new().critical().ca().build()?)?;
|
||||
cert_builder.append_extension(KeyUsage::new()
|
||||
.critical()
|
||||
.key_cert_sign()
|
||||
.crl_sign()
|
||||
.build()?)?;
|
||||
cert_builder.append_extension(
|
||||
KeyUsage::new()
|
||||
.critical()
|
||||
.key_cert_sign()
|
||||
.crl_sign()
|
||||
.build()?,
|
||||
)?;
|
||||
|
||||
let subject_key_identifier =
|
||||
SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(None, None))?;
|
||||
@ -60,7 +63,7 @@ fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> {
|
||||
}
|
||||
|
||||
/// Make a X509 request with the given private key
|
||||
fn mk_request(privkey: &PKey) -> Result<(X509Req), ErrorStack> {
|
||||
fn mk_request(privkey: &PKey<Private>) -> Result<X509Req, ErrorStack> {
|
||||
let mut req_builder = X509ReqBuilder::new()?;
|
||||
req_builder.set_pubkey(&privkey)?;
|
||||
|
||||
@ -78,7 +81,10 @@ fn mk_request(privkey: &PKey) -> Result<(X509Req), ErrorStack> {
|
||||
}
|
||||
|
||||
/// Make a certificate and private key signed by the given CA cert and private key
|
||||
fn mk_ca_signed_cert(ca_cert: &X509Ref, ca_privkey: &PKeyRef) -> Result<(X509, PKey), ErrorStack> {
|
||||
fn mk_ca_signed_cert(
|
||||
ca_cert: &X509Ref,
|
||||
ca_privkey: &PKeyRef<Private>,
|
||||
) -> Result<(X509, PKey<Private>), ErrorStack> {
|
||||
let rsa = Rsa::generate(2048)?;
|
||||
let privkey = PKey::from_rsa(rsa)?;
|
||||
|
||||
@ -88,7 +94,7 @@ fn mk_ca_signed_cert(ca_cert: &X509Ref, ca_privkey: &PKeyRef) -> Result<(X509, P
|
||||
cert_builder.set_version(2)?;
|
||||
let serial_number = {
|
||||
let mut serial = BigNum::new()?;
|
||||
serial.rand(159, MSB_MAYBE_ZERO, false)?;
|
||||
serial.rand(159, MsbOption::MAYBE_ZERO, false)?;
|
||||
serial.to_asn1_integer()?
|
||||
};
|
||||
cert_builder.set_serial_number(&serial_number)?;
|
||||
@ -102,15 +108,17 @@ fn mk_ca_signed_cert(ca_cert: &X509Ref, ca_privkey: &PKeyRef) -> Result<(X509, P
|
||||
|
||||
cert_builder.append_extension(BasicConstraints::new().build()?)?;
|
||||
|
||||
cert_builder.append_extension(KeyUsage::new()
|
||||
.critical()
|
||||
.non_repudiation()
|
||||
.digital_signature()
|
||||
.key_encipherment()
|
||||
.build()?)?;
|
||||
cert_builder.append_extension(
|
||||
KeyUsage::new()
|
||||
.critical()
|
||||
.non_repudiation()
|
||||
.digital_signature()
|
||||
.key_encipherment()
|
||||
.build()?,
|
||||
)?;
|
||||
|
||||
let subject_key_identifier = SubjectKeyIdentifier::new()
|
||||
.build(&cert_builder.x509v3_context(Some(ca_cert), None))?;
|
||||
let subject_key_identifier =
|
||||
SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(Some(ca_cert), None))?;
|
||||
cert_builder.append_extension(subject_key_identifier)?;
|
||||
|
||||
let auth_key_identifier = AuthorityKeyIdentifier::new()
|
||||
@ -137,8 +145,8 @@ fn real_main() -> Result<(), ErrorStack> {
|
||||
|
||||
// Verify that this cert was issued by this ca
|
||||
match ca_cert.issued(&cert) {
|
||||
Err(ver_err) => println!("Failed to verify certificate: {}", ver_err),
|
||||
Ok(()) => println!("Certificate verified!"),
|
||||
X509VerifyResult::OK => println!("Certificate verified!"),
|
||||
ver_err => println!("Failed to verify certificate: {}", ver_err),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Low level AES IGE functionality
|
||||
//! Low level AES IGE and key wrapping functionality
|
||||
//!
|
||||
//! AES ECB, CBC, XTS, CTR, CFB, GCM and other conventional symmetric encryption
|
||||
//! modes are found in [`symm`]. This is the implementation of AES IGE.
|
||||
//! modes are found in [`symm`]. This is the implementation of AES IGE and key wrapping
|
||||
//!
|
||||
//! Advanced Encryption Standard (AES) provides symmetric key cipher that
|
||||
//! the same key is used to encrypt and decrypt data. This implementation
|
||||
@ -22,33 +22,42 @@
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ## AES IGE
|
||||
//! ```rust
|
||||
//! # extern crate openssl;
|
||||
//! extern crate hex;
|
||||
//! use openssl::aes::{AesKey, KeyError, aes_ige};
|
||||
//! use openssl::aes::{AesKey, aes_ige};
|
||||
//! use openssl::symm::Mode;
|
||||
//! use hex::{FromHex, ToHex};
|
||||
//!
|
||||
//! fn decrypt() -> Result<(), KeyError> {
|
||||
//! let raw_key = "000102030405060708090A0B0C0D0E0F";
|
||||
//! let hex_cipher = "12345678901234561234567890123456";
|
||||
//! let randomness = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
|
||||
//! if let (Ok(key_as_u8), Ok(cipher_as_u8), Ok(mut iv_as_u8)) =
|
||||
//! (Vec::from_hex(raw_key), Vec::from_hex(hex_cipher), Vec::from_hex(randomness)) {
|
||||
//! let key = AesKey::new_encrypt(&key_as_u8)?;
|
||||
//! let mut output = vec![0u8; cipher_as_u8.len()];
|
||||
//! aes_ige(&cipher_as_u8, &mut output, &key, &mut iv_as_u8, Mode::Encrypt);
|
||||
//! assert_eq!(output.to_hex(), "a6ad974d5cea1d36d2f367980907ed32");
|
||||
//! }
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
|
||||
//! let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56";
|
||||
//! let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\
|
||||
//! \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
||||
//!
|
||||
//! let key = AesKey::new_encrypt(key).unwrap();
|
||||
//! let mut output = [0u8; 16];
|
||||
//! aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt);
|
||||
//! assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32");
|
||||
//! ```
|
||||
//!
|
||||
//! ## Key wrapping
|
||||
//! ```rust
|
||||
//! use openssl::aes::{AesKey, unwrap_key, wrap_key};
|
||||
//!
|
||||
//! let kek = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
|
||||
//! let key_to_wrap = b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF";
|
||||
//!
|
||||
//! let enc_key = AesKey::new_encrypt(kek).unwrap();
|
||||
//! let mut ciphertext = [0u8; 24];
|
||||
//! wrap_key(&enc_key, None, &mut ciphertext, &key_to_wrap[..]).unwrap();
|
||||
//! let dec_key = AesKey::new_decrypt(kek).unwrap();
|
||||
//! let mut orig_key = [0u8; 16];
|
||||
//! unwrap_key(&dec_key, None, &mut orig_key, &ciphertext[..]).unwrap();
|
||||
//!
|
||||
//! assert_eq!(&orig_key[..], &key_to_wrap[..]);
|
||||
//! ```
|
||||
//!
|
||||
//! # fn main() {
|
||||
//! # decrypt();
|
||||
//! # }
|
||||
use ffi;
|
||||
use std::mem;
|
||||
use libc::c_int;
|
||||
use libc::{c_int, c_uint};
|
||||
use std::{mem, ptr};
|
||||
|
||||
use symm::Mode;
|
||||
|
||||
@ -147,12 +156,87 @@ pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mo
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394)
|
||||
///
|
||||
/// * `key`: The key-encrypting-key to use. Must be a encrypting key
|
||||
/// * `iv`: The IV to use. You must use the same IV for both wrapping and unwrapping
|
||||
/// * `out`: The output buffer to store the ciphertext
|
||||
/// * `in_`: The input buffer, storing the key to be wrapped
|
||||
///
|
||||
/// Returns the number of bytes written into `out`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if
|
||||
/// `out` is not 8 bytes longer than `in_`
|
||||
pub fn wrap_key(
|
||||
key: &AesKey,
|
||||
iv: Option<[u8; 8]>,
|
||||
out: &mut [u8],
|
||||
in_: &[u8],
|
||||
) -> Result<usize, KeyError> {
|
||||
unsafe {
|
||||
assert!(out.len() >= in_.len() + 8); // Ciphertext is 64 bits longer (see 2.2.1)
|
||||
|
||||
let written = ffi::AES_wrap_key(
|
||||
&key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer.
|
||||
iv.as_ref().map_or(ptr::null(), |iv| iv.as_ptr() as *const _),
|
||||
out.as_ptr() as *mut _,
|
||||
in_.as_ptr() as *const _,
|
||||
in_.len() as c_uint,
|
||||
);
|
||||
if written <= 0 {
|
||||
Err(KeyError(()))
|
||||
} else {
|
||||
Ok(written as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unwrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394)
|
||||
///
|
||||
/// * `key`: The key-encrypting-key to decrypt the wrapped key. Must be a decrypting key
|
||||
/// * `iv`: The same IV used for wrapping the key
|
||||
/// * `out`: The buffer to write the unwrapped key to
|
||||
/// * `in_`: The input ciphertext
|
||||
///
|
||||
/// Returns the number of bytes written into `out`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or
|
||||
/// if `in` is not 8 bytes longer than `in_`
|
||||
pub fn unwrap_key(
|
||||
key: &AesKey,
|
||||
iv: Option<[u8; 8]>,
|
||||
out: &mut [u8],
|
||||
in_: &[u8],
|
||||
) -> Result<usize, KeyError> {
|
||||
unsafe {
|
||||
assert!(out.len() + 8 <= in_.len());
|
||||
|
||||
let written = ffi::AES_unwrap_key(
|
||||
&key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer.
|
||||
iv.as_ref().map_or(ptr::null(), |iv| iv.as_ptr() as *const _),
|
||||
out.as_ptr() as *mut _,
|
||||
in_.as_ptr() as *const _,
|
||||
in_.len() as c_uint,
|
||||
);
|
||||
|
||||
if written <= 0 {
|
||||
Err(KeyError(()))
|
||||
} else {
|
||||
Ok(written as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hex::FromHex;
|
||||
|
||||
use symm::Mode;
|
||||
use super::*;
|
||||
use symm::Mode;
|
||||
|
||||
// From https://www.mgp25.com/AESIGE/
|
||||
#[test]
|
||||
@ -177,4 +261,30 @@ mod test {
|
||||
aes_ige(&ct, &mut pt_actual, &key, &mut iv, Mode::Decrypt);
|
||||
assert_eq!(pt_actual, pt);
|
||||
}
|
||||
|
||||
// from the RFC https://tools.ietf.org/html/rfc3394#section-2.2.3
|
||||
#[test]
|
||||
fn test_wrap_unwrap() {
|
||||
let raw_key = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
|
||||
let key_data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap();
|
||||
let expected_ciphertext =
|
||||
Vec::from_hex("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5").unwrap();
|
||||
|
||||
let enc_key = AesKey::new_encrypt(&raw_key).unwrap();
|
||||
let mut wrapped = [0; 24];
|
||||
assert_eq!(
|
||||
wrap_key(&enc_key, None, &mut wrapped, &key_data).unwrap(),
|
||||
24
|
||||
);
|
||||
assert_eq!(&wrapped[..], &expected_ciphertext[..]);
|
||||
|
||||
let dec_key = AesKey::new_decrypt(&raw_key).unwrap();
|
||||
let mut unwrapped = [0; 16];
|
||||
assert_eq!(
|
||||
unwrap_key(&dec_key, None, &mut unwrapped, &wrapped).unwrap(),
|
||||
16
|
||||
);
|
||||
assert_eq!(&unwrapped[..], &key_data[..]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -26,17 +26,19 @@
|
||||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_long, c_char, c_int};
|
||||
use libc::{c_char, c_int, c_long};
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBio;
|
||||
use bn::{BigNum, BigNumRef};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use string::OpensslString;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::ASN1_GENERALIZEDTIME;
|
||||
@ -104,6 +106,15 @@ impl fmt::Display for Asn1TimeRef {
|
||||
}
|
||||
|
||||
impl Asn1Time {
|
||||
fn new() -> Result<Asn1Time, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
unsafe {
|
||||
let handle = cvt_p(ffi::ASN1_TIME_new())?;
|
||||
Ok(Asn1Time::from_ptr(handle))
|
||||
}
|
||||
}
|
||||
|
||||
fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
@ -117,6 +128,41 @@ impl Asn1Time {
|
||||
pub fn days_from_now(days: u32) -> Result<Asn1Time, ErrorStack> {
|
||||
Asn1Time::from_period(days as c_long * 60 * 60 * 24)
|
||||
}
|
||||
|
||||
/// Creates a new time corresponding to the specified ASN1 time string.
|
||||
///
|
||||
/// This corresponds to [`ASN1_TIME_set_string`].
|
||||
///
|
||||
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
|
||||
pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> {
|
||||
unsafe {
|
||||
let s = CString::new(s).unwrap();
|
||||
|
||||
let time = Asn1Time::new()?;
|
||||
cvt(ffi::ASN1_TIME_set_string(time.as_ptr(), s.as_ptr()))?;
|
||||
|
||||
Ok(time)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new time corresponding to the specified X509 time string.
|
||||
///
|
||||
/// This corresponds to [`ASN1_TIME_set_string_X509`].
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// [`ASN1_TIME_set_string_X509`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn from_str_x509(s: &str) -> Result<Asn1Time, ErrorStack> {
|
||||
unsafe {
|
||||
let s = CString::new(s).unwrap();
|
||||
|
||||
let time = Asn1Time::new()?;
|
||||
cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?;
|
||||
|
||||
Ok(time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
@ -161,7 +207,7 @@ impl Asn1StringRef {
|
||||
///
|
||||
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) }
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
|
||||
}
|
||||
|
||||
/// Return the length of the Asn1String (number of bytes)
|
||||
@ -190,15 +236,38 @@ foreign_type_and_impl_send_sync! {
|
||||
pub struct Asn1IntegerRef;
|
||||
}
|
||||
|
||||
impl Asn1Integer {
|
||||
/// Converts a bignum to an `Asn1Integer`.
|
||||
///
|
||||
/// Corresponds to [`BN_to_ASN1_INTEGER`]. Also see
|
||||
/// [`BigNumRef::to_asn1_integer`].
|
||||
///
|
||||
/// [`BN_to_ASN1_INTEGER`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_to_ASN1_INTEGER.html
|
||||
/// [`BigNumRef::to_asn1_integer`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer
|
||||
pub fn from_bn(bn: &BigNumRef) -> Result<Self, ErrorStack> {
|
||||
bn.to_asn1_integer()
|
||||
}
|
||||
}
|
||||
|
||||
impl Asn1IntegerRef {
|
||||
/// Returns value of ASN.1 integer, or -1 if there is an error, and 0 if the integer is Null.
|
||||
///
|
||||
/// OpenSSL documentation at [`ASN1_INTEGER_get`].
|
||||
///
|
||||
/// [`ASN1_INTEGER_get`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
|
||||
#[allow(missing_docs)]
|
||||
#[deprecated(since = "0.10.6", note = "use to_bn instead")]
|
||||
pub fn get(&self) -> i64 {
|
||||
unsafe { ::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 }
|
||||
}
|
||||
|
||||
/// Converts the integer to a `BigNum`.
|
||||
///
|
||||
/// This corresponds to [`ASN1_INTEGER_to_BN`].
|
||||
///
|
||||
/// [`ASN1_INTEGER_to_BN`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
|
||||
pub fn to_bn(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(::ffi::ASN1_INTEGER_to_BN(self.as_ptr(), ptr::null_mut()))
|
||||
.map(|p| BigNum::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers
|
||||
/// see [`bn`].
|
||||
///
|
||||
@ -230,11 +299,11 @@ foreign_type_and_impl_send_sync! {
|
||||
impl Asn1BitStringRef {
|
||||
/// Returns the Asn1BitString as a slice
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) }
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
|
||||
}
|
||||
/// Length of Asn1BitString in number of bytes.
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize }
|
||||
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,11 +354,41 @@ impl fmt::Display for Asn1ObjectRef {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::ASN1_STRING_data;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar {
|
||||
ffi::ASN1_STRING_get0_data(s) as *mut _
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
use ffi::ASN1_STRING_get0_data;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar {
|
||||
ffi::ASN1_STRING_data(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use bn::BigNum;
|
||||
|
||||
/// Tests conversion between BigNum and Asn1Integer.
|
||||
#[test]
|
||||
fn bn_cvt() {
|
||||
fn roundtrip(bn: BigNum) {
|
||||
let large = Asn1Integer::from_bn(&bn).unwrap();
|
||||
assert_eq!(large.to_bn().unwrap(), bn);
|
||||
}
|
||||
|
||||
roundtrip(BigNum::from_dec_str("1000000000000000000000000000000000").unwrap());
|
||||
roundtrip(-BigNum::from_dec_str("1000000000000000000000000000000000").unwrap());
|
||||
roundtrip(BigNum::from_u32(1234).unwrap());
|
||||
roundtrip(-BigNum::from_u32(1234).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn time_from_str() {
|
||||
Asn1Time::from_str("99991231235959Z").unwrap();
|
||||
#[cfg(ossl111)]
|
||||
Asn1Time::from_str_x509("99991231235959Z").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
|
||||
use cvt_p;
|
||||
use error::ErrorStack;
|
||||
@ -66,13 +66,19 @@ impl MemBio {
|
||||
slice::from_raw_parts(ptr as *const _ as *const _, len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio {
|
||||
MemBio(bio)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
use ffi::BIO_new_mem_buf;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
|
||||
ffi::BIO_new_mem_buf(buf as *mut _, len)
|
||||
cfg_if! {
|
||||
if #[cfg(ossl102)] {
|
||||
use ffi::BIO_new_mem_buf;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
|
||||
ffi::BIO_new_mem_buf(buf as *mut _, len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,16 +12,17 @@
|
||||
//! use openssl::bn::BigNum;
|
||||
//! use openssl::error::ErrorStack;
|
||||
//!
|
||||
//! fn bignums() -> Result< (), ErrorStack > {
|
||||
//! fn bignums() -> Result<(), ErrorStack> {
|
||||
//! let a = BigNum::new()?; // a = 0
|
||||
//! let b = BigNum::from_dec_str("1234567890123456789012345")?;
|
||||
//! let c = &a * &b;
|
||||
//! assert_eq!(a,c);
|
||||
//! assert_eq!(a, c);
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! # fn main() {
|
||||
//! # bignums();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! [`BIGNUM`]: https://wiki.openssl.org/index.php/Manual:Bn_internal(3)
|
||||
use ffi;
|
||||
@ -29,43 +30,56 @@ use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::cmp::Ordering;
|
||||
use std::ffi::CString;
|
||||
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
|
||||
use std::{fmt, ptr};
|
||||
use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
|
||||
|
||||
use {cvt, cvt_p, cvt_n};
|
||||
use asn1::Asn1Integer;
|
||||
use error::ErrorStack;
|
||||
use string::OpensslString;
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
|
||||
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
|
||||
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
|
||||
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
|
||||
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
|
||||
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
|
||||
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
|
||||
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192};
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
|
||||
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
|
||||
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
|
||||
};
|
||||
} else {
|
||||
use ffi::{
|
||||
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
|
||||
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
|
||||
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
|
||||
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
|
||||
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
|
||||
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
|
||||
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
|
||||
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
|
||||
};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{BN_get_rfc2409_prime_768, BN_get_rfc2409_prime_1024, BN_get_rfc3526_prime_1536,
|
||||
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
|
||||
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192};
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
|
||||
(*bn).neg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for the most significant bits of a randomly generated `BigNum`.
|
||||
pub struct MsbOption(c_int);
|
||||
|
||||
/// The most significant bit of the number may be 0.
|
||||
pub const MSB_MAYBE_ZERO: MsbOption = MsbOption(-1);
|
||||
impl MsbOption {
|
||||
/// The most significant bit of the number may be 0.
|
||||
pub const MAYBE_ZERO: MsbOption = MsbOption(-1);
|
||||
|
||||
/// The most significant bit of the number must be 1.
|
||||
pub const MSB_ONE: MsbOption = MsbOption(0);
|
||||
/// The most significant bit of the number must be 1.
|
||||
pub const ONE: MsbOption = MsbOption(0);
|
||||
|
||||
/// The most significant two bits of the number must be 1.
|
||||
///
|
||||
/// The number of bits in the product of two such numbers will always be exactly twice the number
|
||||
/// of bits in the original numbers.
|
||||
pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
|
||||
/// The most significant two bits of the number must be 1.
|
||||
///
|
||||
/// The number of bits in the product of two such numbers will always be exactly twice the
|
||||
/// number of bits in the original numbers.
|
||||
pub const TWO_ONES: MsbOption = MsbOption(1);
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::BN_CTX;
|
||||
@ -106,7 +120,7 @@ foreign_type_and_impl_send_sync! {
|
||||
/// Dynamically sized large number impelementation
|
||||
///
|
||||
/// Perform large number mathematics. Create a new BigNum
|
||||
/// with [`new`]. Perform stanard mathematics on large numbers using
|
||||
/// with [`new`]. Perform standard mathematics on large numbers using
|
||||
/// methods from [`Dref<Target = BigNumRef>`]
|
||||
///
|
||||
/// OpenSSL documenation at [`BN_new`].
|
||||
@ -358,17 +372,7 @@ impl BigNumRef {
|
||||
|
||||
/// Returns `true` if `self` is negative.
|
||||
pub fn is_negative(&self) -> bool {
|
||||
self._is_negative()
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
fn _is_negative(&self) -> bool {
|
||||
unsafe { (*self.as_ptr()).neg == 1 }
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
fn _is_negative(&self) -> bool {
|
||||
unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
|
||||
unsafe { BN_is_negative(self.as_ptr()) == 1 }
|
||||
}
|
||||
|
||||
/// Returns the number of significant bits in `self`.
|
||||
@ -396,14 +400,14 @@ impl BigNumRef {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use openssl::bn::{BigNum,MSB_MAYBE_ZERO};
|
||||
/// use openssl::bn::{BigNum, MsbOption};
|
||||
/// use openssl::error::ErrorStack;
|
||||
///
|
||||
/// fn generate_random() -> Result< BigNum, ErrorStack > {
|
||||
/// let mut big = BigNum::new()?;
|
||||
///
|
||||
/// // Generates a 128-bit odd random number
|
||||
/// big.rand(128, MSB_MAYBE_ZERO, true);
|
||||
/// big.rand(128, MsbOption::MAYBE_ZERO, true);
|
||||
/// Ok((big))
|
||||
/// }
|
||||
/// ```
|
||||
@ -419,7 +423,8 @@ impl BigNumRef {
|
||||
bits.into(),
|
||||
msb.0,
|
||||
odd as c_int,
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -435,7 +440,8 @@ impl BigNumRef {
|
||||
bits.into(),
|
||||
msb.0,
|
||||
odd as c_int,
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,7 +487,8 @@ impl BigNumRef {
|
||||
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
||||
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
||||
ptr::null_mut(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -504,7 +511,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -528,7 +536,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +559,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,7 +583,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,7 +615,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -627,7 +639,8 @@ impl BigNumRef {
|
||||
b.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,7 +663,8 @@ impl BigNumRef {
|
||||
b.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,7 +687,8 @@ impl BigNumRef {
|
||||
b.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,7 +709,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,7 +731,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
p.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -738,7 +755,8 @@ impl BigNumRef {
|
||||
p.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,7 +773,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
n.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,7 +795,8 @@ impl BigNumRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,7 +819,8 @@ impl BigNumRef {
|
||||
checks.into(),
|
||||
ctx.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
)).map(|r| r != 0)
|
||||
))
|
||||
.map(|r| r != 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -829,7 +850,8 @@ impl BigNumRef {
|
||||
ctx.as_ptr(),
|
||||
do_trial_division as c_int,
|
||||
ptr::null_mut(),
|
||||
)).map(|r| r != 0)
|
||||
))
|
||||
.map(|r| r != 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1085,7 +1107,8 @@ impl BigNum {
|
||||
n.as_ptr(),
|
||||
n.len() as c_int,
|
||||
ptr::null_mut(),
|
||||
)).map(|p| BigNum::from_ptr(p))
|
||||
))
|
||||
.map(|p| BigNum::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1215,7 +1238,7 @@ macro_rules! delegate {
|
||||
$t::$m(self.deref(), oth.deref())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
|
||||
@ -1345,7 +1368,7 @@ impl Neg for BigNum {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bn::{BigNumContext, BigNum};
|
||||
use bn::{BigNum, BigNumContext};
|
||||
|
||||
#[test]
|
||||
fn test_to_from_slice() {
|
||||
|
||||
@ -8,15 +8,44 @@
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use std::ptr;
|
||||
use error::ErrorStack;
|
||||
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
use error::ErrorStack;
|
||||
use libc::c_uint;
|
||||
use pkey::{HasPrivate, PKeyRef};
|
||||
use stack::StackRef;
|
||||
use x509::{X509Ref, X509};
|
||||
use symm::Cipher;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
use x509::X509;
|
||||
use pkey::PKeyRef;
|
||||
|
||||
use cvt;
|
||||
use cvt_p;
|
||||
bitflags! {
|
||||
pub struct CMSOptions : c_uint {
|
||||
const TEXT = ffi::CMS_TEXT;
|
||||
const CMS_NOCERTS = ffi::CMS_NOCERTS;
|
||||
const NO_CONTENT_VERIFY = ffi::CMS_NO_CONTENT_VERIFY;
|
||||
const NO_ATTR_VERIFY = ffi::CMS_NO_ATTR_VERIFY;
|
||||
const NOSIGS = ffi::CMS_NOSIGS;
|
||||
const NOINTERN = ffi::CMS_NOINTERN;
|
||||
const NO_SIGNER_CERT_VERIFY = ffi::CMS_NO_SIGNER_CERT_VERIFY;
|
||||
const NOVERIFY = ffi::CMS_NOVERIFY;
|
||||
const DETACHED = ffi::CMS_DETACHED;
|
||||
const BINARY = ffi::CMS_BINARY;
|
||||
const NOATTR = ffi::CMS_NOATTR;
|
||||
const NOSMIMECAP = ffi::CMS_NOSMIMECAP;
|
||||
const NOOLDMIMETYPE = ffi::CMS_NOOLDMIMETYPE;
|
||||
const CRLFEOL = ffi::CMS_CRLFEOL;
|
||||
const STREAM = ffi::CMS_STREAM;
|
||||
const NOCRL = ffi::CMS_NOCRL;
|
||||
const PARTIAL = ffi::CMS_PARTIAL;
|
||||
const REUSE_DIGEST = ffi::CMS_REUSE_DIGEST;
|
||||
const USE_KEYID = ffi::CMS_USE_KEYID;
|
||||
const DEBUG_DECRYPT = ffi::CMS_DEBUG_DECRYPT;
|
||||
#[cfg(all(not(libressl), not(ossl101)))]
|
||||
const KEY_PARAM = ffi::CMS_KEY_PARAM;
|
||||
#[cfg(all(not(libressl), not(ossl101), not(ossl102)))]
|
||||
const ASCIICRLF = ffi::CMS_ASCIICRLF;
|
||||
}
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::CMS_ContentInfo;
|
||||
@ -44,7 +73,10 @@ impl CmsContentInfoRef {
|
||||
/// OpenSSL documentation at [`CMS_decrypt`]
|
||||
///
|
||||
/// [`CMS_decrypt`]: https://www.openssl.org/docs/man1.1.0/crypto/CMS_decrypt.html
|
||||
pub fn decrypt(&self, pkey: &PKeyRef, cert: &X509) -> Result<Vec<u8>, ErrorStack> {
|
||||
pub fn decrypt<T>(&self, pkey: &PKeyRef<T>, cert: &X509) -> Result<Vec<u8>, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
let pkey = pkey.as_ptr();
|
||||
let cert = cert.as_ptr();
|
||||
@ -64,6 +96,25 @@ impl CmsContentInfoRef {
|
||||
}
|
||||
}
|
||||
|
||||
to_der! {
|
||||
/// Serializes this CmsContentInfo using DER.
|
||||
///
|
||||
/// OpenSSL documentation at [`i2d_CMS_ContentInfo`]
|
||||
///
|
||||
/// [`i2d_CMS_ContentInfo`]: https://www.openssl.org/docs/man1.0.2/crypto/i2d_CMS_ContentInfo.html
|
||||
to_der,
|
||||
ffi::i2d_CMS_ContentInfo
|
||||
}
|
||||
|
||||
to_pem! {
|
||||
/// Serializes this CmsContentInfo using DER.
|
||||
///
|
||||
/// OpenSSL documentation at [`PEM_write_bio_CMS`]
|
||||
///
|
||||
/// [`PEM_write_bio_CMS`]: https://www.openssl.org/docs/man1.1.0/man3/PEM_write_bio_CMS.html
|
||||
to_pem,
|
||||
ffi::PEM_write_bio_CMS
|
||||
}
|
||||
}
|
||||
|
||||
impl CmsContentInfo {
|
||||
@ -76,12 +127,144 @@ impl CmsContentInfo {
|
||||
unsafe {
|
||||
let bio = MemBioSlice::new(smime)?;
|
||||
|
||||
let cms = cvt_p(ffi::SMIME_read_CMS(
|
||||
bio.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
let cms = cvt_p(ffi::SMIME_read_CMS(bio.as_ptr(), ptr::null_mut()))?;
|
||||
|
||||
Ok(CmsContentInfo::from_ptr(cms))
|
||||
}
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded ContentInfo structure.
|
||||
///
|
||||
/// This corresponds to [`d2i_CMS_ContentInfo`].
|
||||
///
|
||||
/// [`d2i_CMS_ContentInfo`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html
|
||||
from_der,
|
||||
CmsContentInfo,
|
||||
ffi::d2i_CMS_ContentInfo
|
||||
}
|
||||
|
||||
from_pem! {
|
||||
/// Deserializes a PEM-encoded ContentInfo structure.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_CMS`].
|
||||
///
|
||||
/// [`PEM_read_bio_CMS`]: https://www.openssl.org/docs/man1.1.0/man3/PEM_read_bio_CMS.html
|
||||
from_pem,
|
||||
CmsContentInfo,
|
||||
ffi::PEM_read_bio_CMS
|
||||
}
|
||||
|
||||
/// Given a signing cert `signcert`, private key `pkey`, a certificate stack `certs`,
|
||||
/// data `data` and flags `flags`, create a CmsContentInfo struct.
|
||||
///
|
||||
/// All arguments are optional.
|
||||
///
|
||||
/// OpenSSL documentation at [`CMS_sign`]
|
||||
///
|
||||
/// [`CMS_sign`]: https://www.openssl.org/docs/manmaster/man3/CMS_sign.html
|
||||
pub fn sign<T>(
|
||||
signcert: Option<&X509Ref>,
|
||||
pkey: Option<&PKeyRef<T>>,
|
||||
certs: Option<&StackRef<X509>>,
|
||||
data: Option<&[u8]>,
|
||||
flags: CMSOptions,
|
||||
) -> Result<CmsContentInfo, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
let signcert = signcert.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let pkey = pkey.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let data_bio = match data {
|
||||
Some(data) => Some(MemBioSlice::new(data)?),
|
||||
None => None,
|
||||
};
|
||||
let data_bio_ptr = data_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let certs = certs.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
|
||||
let cms = cvt_p(ffi::CMS_sign(
|
||||
signcert,
|
||||
pkey,
|
||||
certs,
|
||||
data_bio_ptr,
|
||||
flags.bits(),
|
||||
))?;
|
||||
|
||||
Ok(CmsContentInfo::from_ptr(cms))
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a certificate stack `certs`, data `data`, cipher `cipher` and flags `flags`,
|
||||
/// create a CmsContentInfo struct.
|
||||
///
|
||||
/// OpenSSL documentation at [`CMS_encrypt`]
|
||||
///
|
||||
/// [`CMS_encrypt`]: https://www.openssl.org/docs/manmaster/man3/CMS_encrypt.html
|
||||
pub fn encrypt(
|
||||
certs: &StackRef<X509>,
|
||||
data: &[u8],
|
||||
cipher: Cipher,
|
||||
flags: CMSOptions,
|
||||
) -> Result<CmsContentInfo, ErrorStack>
|
||||
{
|
||||
unsafe {
|
||||
let data_bio = MemBioSlice::new(data)?;
|
||||
|
||||
let cms = cvt_p(ffi::CMS_encrypt(
|
||||
certs.as_ptr(),
|
||||
data_bio.as_ptr(),
|
||||
cipher.as_ptr(),
|
||||
flags.bits(),
|
||||
))?;
|
||||
|
||||
Ok(CmsContentInfo::from_ptr(cms))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use stack::Stack;
|
||||
use x509::X509;
|
||||
use pkcs12::Pkcs12;
|
||||
|
||||
#[test]
|
||||
fn cms_encrypt_decrypt() {
|
||||
// load cert with public key only
|
||||
let pub_cert_bytes = include_bytes!("../test/cms_pubkey.der");
|
||||
let pub_cert = X509::from_der(pub_cert_bytes).expect("failed to load pub cert");
|
||||
|
||||
// load cert with private key
|
||||
let priv_cert_bytes = include_bytes!("../test/cms.p12");
|
||||
let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert");
|
||||
let priv_cert = priv_cert.parse("mypass").expect("failed to parse priv cert");
|
||||
|
||||
// encrypt cms message using public key cert
|
||||
let input = String::from("My Message");
|
||||
let mut cert_stack = Stack::new().expect("failed to create stack");
|
||||
cert_stack.push(pub_cert).expect("failed to add pub cert to stack");
|
||||
|
||||
let encrypt = CmsContentInfo::encrypt(&cert_stack, &input.as_bytes(), Cipher::des_ede3_cbc(), CMSOptions::empty())
|
||||
.expect("failed create encrypted cms");
|
||||
|
||||
// decrypt cms message using private key cert (DER)
|
||||
{
|
||||
let encrypted_der = encrypt.to_der().expect("failed to create der from cms");
|
||||
let decrypt = CmsContentInfo::from_der(&encrypted_der).expect("failed read cms from der");
|
||||
let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms");
|
||||
let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content");
|
||||
assert_eq!(input, decrypt);
|
||||
}
|
||||
|
||||
// decrypt cms message using private key cert (PEM)
|
||||
{
|
||||
let encrypted_pem = encrypt.to_pem().expect("failed to create pem from cms");
|
||||
let decrypt = CmsContentInfo::from_pem(&encrypted_pem).expect("failed read cms from pem");
|
||||
let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms");
|
||||
let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content");
|
||||
assert_eq!(input, decrypt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
#![doc(hidden)]
|
||||
#![deprecated(since = "0.9.20")]
|
||||
use string::OpensslString;
|
||||
|
||||
#[deprecated(note = "renamed to OpensslString", since = "0.9.7")]
|
||||
pub type CryptoString = OpensslString;
|
||||
124
openssl/src/derive.rs
Normal file
124
openssl/src/derive.rs
Normal file
@ -0,0 +1,124 @@
|
||||
//! Shared secret derivation.
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
use error::ErrorStack;
|
||||
use pkey::{HasPrivate, HasPublic, PKeyRef};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
/// A type used to derive a shared secret between two keys.
|
||||
pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>);
|
||||
|
||||
unsafe impl<'a> Sync for Deriver<'a> {}
|
||||
unsafe impl<'a> Send for Deriver<'a> {}
|
||||
|
||||
impl<'a> Deriver<'a> {
|
||||
/// Creates a new `Deriver` using the provided private key.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_derive_init`].
|
||||
///
|
||||
/// [`EVP_PKEY_derive_init`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
|
||||
pub fn new<T>(key: &'a PKeyRef<T>) -> Result<Deriver<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
cvt_p(ffi::EVP_PKEY_CTX_new(key.as_ptr(), ptr::null_mut()))
|
||||
.map(|p| Deriver(p, PhantomData))
|
||||
.and_then(|ctx| cvt(ffi::EVP_PKEY_derive_init(ctx.0)).map(|_| ctx))
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the peer key used for secret derivation.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_derive_set_peer`]:
|
||||
///
|
||||
/// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
|
||||
pub fn set_peer<T>(&mut self, key: &'a PKeyRef<T>) -> Result<(), ErrorStack>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Returns the size of the shared secret.
|
||||
///
|
||||
/// It can be used to size the buffer passed to [`Deriver::derive`].
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_derive`].
|
||||
///
|
||||
/// [`Deriver::derive`]: #method.derive
|
||||
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
|
||||
pub fn len(&mut self) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
cvt(ffi::EVP_PKEY_derive(self.0, ptr::null_mut(), &mut len)).map(|_| len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Derives a shared secret between the two keys, writing it into the buffer.
|
||||
///
|
||||
/// Returns the number of bytes written.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_derive`].
|
||||
///
|
||||
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
|
||||
pub fn derive(&mut self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
|
||||
let mut len = buf.len();
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_derive(
|
||||
self.0,
|
||||
buf.as_mut_ptr() as *mut _,
|
||||
&mut len,
|
||||
))
|
||||
.map(|_| len)
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenience function which derives a shared secret and returns it in a new buffer.
|
||||
///
|
||||
/// This simply wraps [`Deriver::len`] and [`Deriver::derive`].
|
||||
///
|
||||
/// [`Deriver::len`]: #method.len
|
||||
/// [`Deriver::derive`]: #method.derive
|
||||
pub fn derive_to_vec(&mut self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let len = self.len()?;
|
||||
let mut buf = vec![0; len];
|
||||
let len = self.derive(&mut buf)?;
|
||||
buf.truncate(len);
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
use ec::{EcGroup, EcKey};
|
||||
use nid::Nid;
|
||||
use pkey::PKey;
|
||||
|
||||
#[test]
|
||||
fn derive_without_peer() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let ec_key = EcKey::generate(&group).unwrap();
|
||||
let pkey = PKey::from_ec_key(ec_key).unwrap();
|
||||
let mut deriver = Deriver::new(&pkey).unwrap();
|
||||
deriver.derive_to_vec().unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ec_key_derive() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let ec_key = EcKey::generate(&group).unwrap();
|
||||
let ec_key2 = EcKey::generate(&group).unwrap();
|
||||
let pkey = PKey::from_ec_key(ec_key).unwrap();
|
||||
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
|
||||
let mut deriver = Deriver::new(&pkey).unwrap();
|
||||
deriver.set_peer(&pkey2).unwrap();
|
||||
let shared = deriver.derive_to_vec().unwrap();
|
||||
assert!(!shared.is_empty());
|
||||
}
|
||||
}
|
||||
@ -1,104 +1,138 @@
|
||||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bn::BigNum;
|
||||
use pkey::{HasParams, Params};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::DH;
|
||||
fn drop = ffi::DH_free;
|
||||
|
||||
pub struct Dh;
|
||||
pub struct Dh<T>;
|
||||
|
||||
pub struct DhRef;
|
||||
pub struct DhRef<T>;
|
||||
}
|
||||
|
||||
impl DhRef {
|
||||
to_pem!(ffi::PEM_write_bio_DHparams);
|
||||
to_der!(ffi::i2d_DHparams);
|
||||
impl<T> DhRef<T>
|
||||
where
|
||||
T: HasParams,
|
||||
{
|
||||
to_pem! {
|
||||
/// Serializes the parameters into a PEM-encoded PKCS#3 DHparameter structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN DH PARAMETERS-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_DHparams`].
|
||||
///
|
||||
/// [`PEM_write_bio_DHparams`]: https://www.openssl.org/docs/manmaster/man3/PEM_write_bio_DHparams.html
|
||||
params_to_pem,
|
||||
ffi::PEM_write_bio_DHparams
|
||||
}
|
||||
|
||||
to_der! {
|
||||
/// Serializes the parameters into a DER-encoded PKCS#3 DHparameter structure.
|
||||
///
|
||||
/// This corresponds to [`i2d_DHparams`].
|
||||
///
|
||||
/// [`i2d_DHparams`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_DHparams.html
|
||||
params_to_der,
|
||||
ffi::i2d_DHparams
|
||||
}
|
||||
}
|
||||
|
||||
impl Dh {
|
||||
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh, ErrorStack> {
|
||||
impl Dh<Params> {
|
||||
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
let dh = Dh(cvt_p(ffi::DH_new())?);
|
||||
cvt(compat::DH_set0_pqg(
|
||||
dh.0,
|
||||
p.as_ptr(),
|
||||
q.as_ptr(),
|
||||
g.as_ptr(),
|
||||
))?;
|
||||
let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?);
|
||||
cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
|
||||
mem::forget((p, g, q));
|
||||
Ok(dh)
|
||||
}
|
||||
}
|
||||
|
||||
from_pem!(Dh, ffi::PEM_read_bio_DHparams);
|
||||
from_der!(Dh, ffi::d2i_DHparams);
|
||||
from_pem! {
|
||||
/// Deserializes a PEM-encoded PKCS#3 DHpararameters structure.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN DH PARAMETERS-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_DHparams`].
|
||||
///
|
||||
/// [`PEM_read_bio_DHparams`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_DHparams.html
|
||||
params_from_pem,
|
||||
Dh<Params>,
|
||||
ffi::PEM_read_bio_DHparams
|
||||
}
|
||||
|
||||
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
pub fn get_1024_160() -> Result<Dh, ErrorStack> {
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded PKCS#3 DHparameters structure.
|
||||
///
|
||||
/// This corresponds to [`d2i_DHparams`].
|
||||
///
|
||||
/// [`d2i_DHparams`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_DHparams.html
|
||||
params_from_der,
|
||||
Dh<Params>,
|
||||
ffi::d2i_DHparams
|
||||
}
|
||||
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
pub fn get_1024_160() -> Result<Dh<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
cvt_p(ffi::DH_get_1024_160()).map(Dh)
|
||||
cvt_p(ffi::DH_get_1024_160()).map(|p| Dh::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
pub fn get_2048_224() -> Result<Dh, ErrorStack> {
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
pub fn get_2048_224() -> Result<Dh<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
cvt_p(ffi::DH_get_2048_224()).map(Dh)
|
||||
cvt_p(ffi::DH_get_2048_224()).map(|p| Dh::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
pub fn get_2048_256() -> Result<Dh, ErrorStack> {
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
pub fn get_2048_256() -> Result<Dh<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
cvt_p(ffi::DH_get_2048_256()).map(Dh)
|
||||
cvt_p(ffi::DH_get_2048_256()).map(|p| Dh::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
pub use ffi::DH_set0_pqg;
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
|
||||
pub unsafe fn DH_set0_pqg(
|
||||
dh: *mut ffi::DH,
|
||||
p: *mut ffi::BIGNUM,
|
||||
q: *mut ffi::BIGNUM,
|
||||
g: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
(*dh).p = p;
|
||||
(*dh).q = q;
|
||||
(*dh).g = g;
|
||||
1
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
use ffi::DH_set0_pqg;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DH_set0_pqg(
|
||||
dh: *mut ffi::DH,
|
||||
p: *mut ffi::BIGNUM,
|
||||
q: *mut ffi::BIGNUM,
|
||||
g: *mut ffi::BIGNUM,
|
||||
) -> ::libc::c_int {
|
||||
(*dh).p = p;
|
||||
(*dh).q = q;
|
||||
(*dh).g = g;
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use dh::Dh;
|
||||
use bn::BigNum;
|
||||
use ssl::{SslMethod, SslContext};
|
||||
use dh::Dh;
|
||||
use ssl::{SslContext, SslMethod};
|
||||
|
||||
#[test]
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
fn test_dh_rfc5114() {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
let dh1 = Dh::get_1024_160().unwrap();
|
||||
@ -113,31 +147,25 @@ mod tests {
|
||||
fn test_dh() {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
let p = BigNum::from_hex_str(
|
||||
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
|
||||
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
|
||||
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
|
||||
2E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF1230\
|
||||
7F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9\
|
||||
A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251C\
|
||||
CACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE\
|
||||
621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D227\
|
||||
6E11715F693877FAD7EF09CADB094AE91E1A1597",
|
||||
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF\
|
||||
4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B47\
|
||||
58C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B6\
|
||||
3ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5\
|
||||
140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710\
|
||||
C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597",
|
||||
).unwrap();
|
||||
let g = BigNum::from_hex_str(
|
||||
"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0\
|
||||
BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773\
|
||||
BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2D\
|
||||
DF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428E\
|
||||
BC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BF\
|
||||
FE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7\
|
||||
D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92\
|
||||
B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148\
|
||||
D47954515E2327CFEF98C582664B4C0F6CC41659",
|
||||
"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED\
|
||||
4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A\
|
||||
57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5\
|
||||
045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E\
|
||||
052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67E\
|
||||
B6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659",
|
||||
).unwrap();
|
||||
let q = BigNum::from_hex_str(
|
||||
"8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F\
|
||||
5FBD3",
|
||||
).unwrap();
|
||||
"8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3",
|
||||
)
|
||||
.unwrap();
|
||||
let dh = Dh::from_params(p, g, q).unwrap();
|
||||
ctx.set_tmp_dh(&dh).unwrap();
|
||||
}
|
||||
@ -146,15 +174,15 @@ mod tests {
|
||||
fn test_dh_from_pem() {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
let params = include_bytes!("../test/dhparams.pem");
|
||||
let dh = Dh::from_pem(params).unwrap();
|
||||
let dh = Dh::params_from_pem(params).unwrap();
|
||||
ctx.set_tmp_dh(&dh).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dh_from_der() {
|
||||
let params = include_bytes!("../test/dhparams.pem");
|
||||
let dh = Dh::from_pem(params).unwrap();
|
||||
let der = dh.to_der().unwrap();
|
||||
Dh::from_der(&der).unwrap();
|
||||
let dh = Dh::params_from_pem(params).unwrap();
|
||||
let der = dh.params_to_der().unwrap();
|
||||
Dh::params_from_der(&der).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,18 +6,18 @@
|
||||
//! without the private key.
|
||||
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::{c_int, c_char, c_void};
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBioSlice;
|
||||
use bn::BigNumRef;
|
||||
use bn::{BigNum, BigNumRef};
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb_old};
|
||||
use pkey::{HasParams, HasPrivate, HasPublic, Private, Public};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::DSA;
|
||||
fn drop = ffi::DSA_free;
|
||||
|
||||
@ -42,7 +42,9 @@ foreign_type_and_impl_send_sync! {
|
||||
/// ```
|
||||
/// use openssl::dsa::Dsa;
|
||||
/// use openssl::error::ErrorStack;
|
||||
/// fn create_dsa() -> Result< Dsa, ErrorStack > {
|
||||
/// use openssl::pkey::Private;
|
||||
///
|
||||
/// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> {
|
||||
/// let sign = Dsa::generate(2048)?;
|
||||
/// Ok(sign)
|
||||
/// }
|
||||
@ -50,98 +52,155 @@ foreign_type_and_impl_send_sync! {
|
||||
/// # create_dsa();
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct Dsa;
|
||||
pub struct Dsa<T>;
|
||||
/// Reference to [`Dsa`].
|
||||
///
|
||||
/// [`Dsa`]: struct.Dsa.html
|
||||
pub struct DsaRef;
|
||||
pub struct DsaRef<T>;
|
||||
}
|
||||
|
||||
impl DsaRef {
|
||||
private_key_to_pem!(ffi::PEM_write_bio_DSAPrivateKey);
|
||||
public_key_to_pem!(ffi::PEM_write_bio_DSA_PUBKEY);
|
||||
impl<T> Clone for Dsa<T> {
|
||||
fn clone(&self) -> Dsa<T> {
|
||||
(**self).to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
private_key_to_der!(ffi::i2d_DSAPrivateKey);
|
||||
public_key_to_der!(ffi::i2d_DSAPublicKey);
|
||||
impl<T> ToOwned for DsaRef<T> {
|
||||
type Owned = Dsa<T>;
|
||||
|
||||
/// Returns the maximum size of the signature output by `self` in bytes. Returns
|
||||
/// None if the keys are uninitialized.
|
||||
fn to_owned(&self) -> Dsa<T> {
|
||||
unsafe {
|
||||
ffi::DSA_up_ref(self.as_ptr());
|
||||
Dsa::from_ptr(self.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DsaRef<T>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
private_key_to_pem! {
|
||||
/// Serializes the private key to a PEM-encoded DSAPrivateKey structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_DSAPrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_DSAPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSAPrivateKey.html
|
||||
private_key_to_pem,
|
||||
/// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_DSAPrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_DSAPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSAPrivateKey.html
|
||||
private_key_to_pem_passphrase,
|
||||
ffi::PEM_write_bio_DSAPrivateKey
|
||||
}
|
||||
|
||||
to_pem! {
|
||||
/// Serialies the public key into a PEM-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_DSA_PUBKEY`].
|
||||
///
|
||||
/// [`PEM_write_bio_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSA_PUBKEY.html
|
||||
public_key_to_pem,
|
||||
ffi::PEM_write_bio_DSA_PUBKEY
|
||||
}
|
||||
|
||||
to_der! {
|
||||
/// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// This corresponds to [`i2d_DSA_PUBKEY`].
|
||||
///
|
||||
/// [`i2d_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_DSA_PUBKEY.html
|
||||
public_key_to_der,
|
||||
ffi::i2d_DSA_PUBKEY
|
||||
}
|
||||
|
||||
/// Returns a reference to the public key component of `self`.
|
||||
pub fn pub_key(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let mut pub_key = ptr::null();
|
||||
DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
|
||||
BigNumRef::from_ptr(pub_key as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DsaRef<T>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
/// Returns a reference to the private key component of `self`.
|
||||
pub fn priv_key(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let mut priv_key = ptr::null();
|
||||
DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
|
||||
BigNumRef::from_ptr(priv_key as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DsaRef<T>
|
||||
where
|
||||
T: HasParams,
|
||||
{
|
||||
/// Returns the maximum size of the signature output by `self` in bytes.
|
||||
///
|
||||
/// OpenSSL documentation at [`DSA_size`]
|
||||
///
|
||||
/// [`DSA_size`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_size.html
|
||||
// FIXME should return u32
|
||||
pub fn size(&self) -> Option<u32> {
|
||||
if self.q().is_some() {
|
||||
unsafe { Some(ffi::DSA_size(self.as_ptr()) as u32) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
pub fn size(&self) -> u32 {
|
||||
unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
|
||||
}
|
||||
|
||||
/// Returns the DSA prime parameter of `self`.
|
||||
pub fn p(&self) -> Option<&BigNumRef> {
|
||||
pub fn p(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let p = compat::pqg(self.as_ptr())[0];
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(BigNumRef::from_ptr(p as *mut _))
|
||||
}
|
||||
let mut p = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
|
||||
BigNumRef::from_ptr(p as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the DSA sub-prime parameter of `self`.
|
||||
pub fn q(&self) -> Option<&BigNumRef> {
|
||||
pub fn q(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let q = compat::pqg(self.as_ptr())[1];
|
||||
if q.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(BigNumRef::from_ptr(q as *mut _))
|
||||
}
|
||||
let mut q = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
|
||||
BigNumRef::from_ptr(q as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the DSA base parameter of `self`.
|
||||
pub fn g(&self) -> Option<&BigNumRef> {
|
||||
pub fn g(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let g = compat::pqg(self.as_ptr())[2];
|
||||
if g.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(BigNumRef::from_ptr(g as *mut _))
|
||||
}
|
||||
let mut g = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
|
||||
BigNumRef::from_ptr(g as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the DSA includes a public key, used to confirm the authenticity
|
||||
/// of the message.
|
||||
pub fn has_public_key(&self) -> bool {
|
||||
unsafe { !compat::keys(self.as_ptr())[0].is_null() }
|
||||
}
|
||||
|
||||
/// Returns whether the DSA includes a private key, used to prove the authenticity
|
||||
/// of a message.
|
||||
pub fn has_private_key(&self) -> bool {
|
||||
unsafe { !compat::keys(self.as_ptr())[1].is_null() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Dsa {
|
||||
impl Dsa<Private> {
|
||||
/// Generate a DSA key pair.
|
||||
///
|
||||
/// Calls [`DSA_generate_parameters_ex`] to populate the `p`, `g`, and `q` values.
|
||||
/// These values are used to generate the key pair with [`DSA_generate_key`].
|
||||
///
|
||||
/// The `bits` parameter coresponds to the length of the prime `p`.
|
||||
/// The `bits` parameter corresponds to the length of the prime `p`.
|
||||
///
|
||||
/// [`DSA_generate_parameters_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_parameters_ex.html
|
||||
/// [`DSA_generate_key`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_key.html
|
||||
pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> {
|
||||
pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
|
||||
ffi::init();
|
||||
unsafe {
|
||||
let dsa = Dsa(cvt_p(ffi::DSA_new())?);
|
||||
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
|
||||
cvt(ffi::DSA_generate_parameters_ex(
|
||||
dsa.0,
|
||||
bits as c_int,
|
||||
@ -156,75 +215,152 @@ impl Dsa {
|
||||
}
|
||||
}
|
||||
|
||||
private_key_from_pem!(Dsa, ffi::PEM_read_bio_DSAPrivateKey);
|
||||
private_key_from_der!(Dsa, ffi::d2i_DSAPrivateKey);
|
||||
public_key_from_pem!(Dsa, ffi::PEM_read_bio_DSA_PUBKEY);
|
||||
public_key_from_der!(Dsa, ffi::d2i_DSAPublicKey);
|
||||
|
||||
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
|
||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
|
||||
where
|
||||
F: FnOnce(&mut [c_char]) -> usize,
|
||||
{
|
||||
/// Create a DSA key pair with the given parameters
|
||||
///
|
||||
/// `p`, `q` and `g` are the common parameters.
|
||||
/// `priv_key` is the private component of the key pair.
|
||||
/// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p`
|
||||
pub fn from_private_components(
|
||||
p: BigNum,
|
||||
q: BigNum,
|
||||
g: BigNum,
|
||||
priv_key: BigNum,
|
||||
pub_key: BigNum,
|
||||
) -> Result<Dsa<Private>, ErrorStack> {
|
||||
ffi::init();
|
||||
let mut cb = CallbackState::new(pass_cb);
|
||||
let mem_bio = MemBioSlice::new(buf)?;
|
||||
|
||||
unsafe {
|
||||
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
||||
let dsa = cvt_p(ffi::PEM_read_bio_DSAPrivateKey(
|
||||
mem_bio.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
Some(invoke_passwd_cb_old::<F>),
|
||||
cb_ptr,
|
||||
))?;
|
||||
Ok(Dsa(dsa))
|
||||
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
|
||||
cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
|
||||
mem::forget((p, q, g));
|
||||
cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
|
||||
mem::forget((pub_key, priv_key));
|
||||
Ok(dsa)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Dsa {
|
||||
impl Dsa<Public> {
|
||||
from_pem! {
|
||||
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_DSA_PUBKEY`].
|
||||
///
|
||||
/// [`PEM_read_bio_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_DSA_PUBKEY.html
|
||||
public_key_from_pem,
|
||||
Dsa<Public>,
|
||||
ffi::PEM_read_bio_DSA_PUBKEY
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key.
|
||||
///
|
||||
/// This corresponds to [`d2i_DSA_PUBKEY`].
|
||||
///
|
||||
/// [`d2i_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_DSA_PUBKEY.html
|
||||
public_key_from_der,
|
||||
Dsa<Public>,
|
||||
ffi::d2i_DSA_PUBKEY
|
||||
}
|
||||
|
||||
/// Create a new DSA key with only public components.
|
||||
///
|
||||
/// `p`, `q` and `g` are the common parameters.
|
||||
/// `pub_key` is the public component of the key.
|
||||
pub fn from_public_components(
|
||||
p: BigNum,
|
||||
q: BigNum,
|
||||
g: BigNum,
|
||||
pub_key: BigNum,
|
||||
) -> Result<Dsa<Public>, ErrorStack> {
|
||||
ffi::init();
|
||||
unsafe {
|
||||
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
|
||||
cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
|
||||
mem::forget((p, q, g));
|
||||
cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
|
||||
mem::forget(pub_key);
|
||||
Ok(dsa)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for Dsa<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DSA")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
use ffi::{self, BIGNUM, DSA};
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DSA_get0_pqg(
|
||||
d: *mut ffi::DSA,
|
||||
p: *mut *const ffi::BIGNUM,
|
||||
q: *mut *const ffi::BIGNUM,
|
||||
g: *mut *const ffi::BIGNUM)
|
||||
{
|
||||
if !p.is_null() {
|
||||
*p = (*d).p;
|
||||
}
|
||||
if !q.is_null() {
|
||||
*q = (*d).q;
|
||||
}
|
||||
if !g.is_null() {
|
||||
*g = (*d).g;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
|
||||
let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null());
|
||||
ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g);
|
||||
[p, q, g]
|
||||
}
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DSA_get0_key(
|
||||
d: *mut ffi::DSA,
|
||||
pub_key: *mut *const ffi::BIGNUM,
|
||||
priv_key: *mut *const ffi::BIGNUM)
|
||||
{
|
||||
if !pub_key.is_null() {
|
||||
*pub_key = (*d).pub_key;
|
||||
}
|
||||
if !priv_key.is_null() {
|
||||
*priv_key = (*d).priv_key;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
|
||||
let (mut pub_key, mut priv_key) = (ptr::null(), ptr::null());
|
||||
ffi::DSA_get0_key(d, &mut pub_key, &mut priv_key);
|
||||
[pub_key, priv_key]
|
||||
}
|
||||
}
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DSA_set0_key(
|
||||
d: *mut ffi::DSA,
|
||||
pub_key: *mut ffi::BIGNUM,
|
||||
priv_key: *mut ffi::BIGNUM) -> c_int
|
||||
{
|
||||
(*d).pub_key = pub_key;
|
||||
(*d).priv_key = priv_key;
|
||||
1
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
mod compat {
|
||||
use ffi::{BIGNUM, DSA};
|
||||
|
||||
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
|
||||
[(*d).p, (*d).q, (*d).g]
|
||||
}
|
||||
|
||||
pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
|
||||
[(*d).pub_key, (*d).priv_key]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DSA_set0_pqg(
|
||||
d: *mut ffi::DSA,
|
||||
p: *mut ffi::BIGNUM,
|
||||
q: *mut ffi::BIGNUM,
|
||||
g: *mut ffi::BIGNUM) -> c_int
|
||||
{
|
||||
(*d).p = p;
|
||||
(*d).q = q;
|
||||
(*d).g = g;
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use symm::Cipher;
|
||||
|
||||
use super::*;
|
||||
use bn::BigNumContext;
|
||||
use hash::MessageDigest;
|
||||
use pkey::PKey;
|
||||
use sign::{Signer, Verifier};
|
||||
|
||||
#[test]
|
||||
pub fn test_generate() {
|
||||
@ -232,30 +368,91 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_password() {
|
||||
let key = include_bytes!("../test/dsa-encrypted.pem");
|
||||
Dsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
|
||||
fn test_pubkey_generation() {
|
||||
let dsa = Dsa::generate(1024).unwrap();
|
||||
let p = dsa.p();
|
||||
let g = dsa.g();
|
||||
let priv_key = dsa.priv_key();
|
||||
let pub_key = dsa.pub_key();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let mut calc = BigNum::new().unwrap();
|
||||
calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
|
||||
assert_eq!(&calc, pub_key)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_password() {
|
||||
fn test_priv_key_from_parts() {
|
||||
let p = BigNum::from_u32(283).unwrap();
|
||||
let q = BigNum::from_u32(47).unwrap();
|
||||
let g = BigNum::from_u32(60).unwrap();
|
||||
let priv_key = BigNum::from_u32(15).unwrap();
|
||||
let pub_key = BigNum::from_u32(207).unwrap();
|
||||
|
||||
let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
|
||||
assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
|
||||
assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
|
||||
assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
|
||||
assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
|
||||
assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pub_key_from_parts() {
|
||||
let p = BigNum::from_u32(283).unwrap();
|
||||
let q = BigNum::from_u32(47).unwrap();
|
||||
let g = BigNum::from_u32(60).unwrap();
|
||||
let pub_key = BigNum::from_u32(207).unwrap();
|
||||
|
||||
let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
|
||||
assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
|
||||
assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
|
||||
assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
|
||||
assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature() {
|
||||
const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let dsa_ref = Dsa::generate(1024).unwrap();
|
||||
|
||||
let p = dsa_ref.p();
|
||||
let q = dsa_ref.q();
|
||||
let g = dsa_ref.g();
|
||||
|
||||
let pub_key = dsa_ref.pub_key();
|
||||
let priv_key = dsa_ref.priv_key();
|
||||
|
||||
let priv_key = Dsa::from_private_components(
|
||||
BigNumRef::to_owned(p).unwrap(),
|
||||
BigNumRef::to_owned(q).unwrap(),
|
||||
BigNumRef::to_owned(g).unwrap(),
|
||||
BigNumRef::to_owned(priv_key).unwrap(),
|
||||
BigNumRef::to_owned(pub_key).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let priv_key = PKey::from_dsa(priv_key).unwrap();
|
||||
|
||||
let pub_key = Dsa::from_public_components(
|
||||
BigNumRef::to_owned(p).unwrap(),
|
||||
BigNumRef::to_owned(q).unwrap(),
|
||||
BigNumRef::to_owned(g).unwrap(),
|
||||
BigNumRef::to_owned(pub_key).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let pub_key = PKey::from_dsa(pub_key).unwrap();
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
|
||||
signer.update(TEST_DATA).unwrap();
|
||||
|
||||
let signature = signer.sign_to_vec().unwrap();
|
||||
let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
|
||||
verifier.update(TEST_DATA).unwrap();
|
||||
assert!(verifier.verify(&signature[..]).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone() {
|
||||
let key = Dsa::generate(2048).unwrap();
|
||||
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
|
||||
.unwrap();
|
||||
Dsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
|
||||
assert!(Dsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_password_callback() {
|
||||
let mut password_queried = false;
|
||||
let key = include_bytes!("../test/dsa-encrypted.pem");
|
||||
Dsa::private_key_from_pem_callback(key, |password| {
|
||||
password_queried = true;
|
||||
password[..6].copy_from_slice(b"mypass");
|
||||
Ok(6)
|
||||
}).unwrap();
|
||||
|
||||
assert!(password_queried);
|
||||
drop(key.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
//!
|
||||
//! ```
|
||||
//! use openssl::ec::{EcGroup, EcPoint};
|
||||
//! use openssl::nid;
|
||||
//! use openssl::nid::Nid;
|
||||
//! use openssl::error::ErrorStack;
|
||||
//! fn get_ec_point() -> Result< EcPoint, ErrorStack > {
|
||||
//! let group = EcGroup::from_curve_name(nid::SECP224R1)?;
|
||||
//! fn get_ec_point() -> Result<EcPoint, ErrorStack> {
|
||||
//! let group = EcGroup::from_curve_name(Nid::SECP224R1)?;
|
||||
//! let point = EcPoint::new(&group)?;
|
||||
//! Ok(point)
|
||||
//! }
|
||||
@ -33,51 +33,15 @@
|
||||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use libc::c_int;
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_n, cvt_p, init};
|
||||
use bn::{BigNumRef, BigNumContextRef};
|
||||
use bn::{BigNumContextRef, BigNumRef};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
|
||||
/// Compressed conversion from point value (Default)
|
||||
pub const POINT_CONVERSION_COMPRESSED: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
/// Uncompressed conversion from point value (Binary curve default)
|
||||
pub const POINT_CONVERSION_UNCOMPRESSED: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED);
|
||||
|
||||
/// Performs both compressed and uncompressed conversions
|
||||
pub const POINT_CONVERSION_HYBRID: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID);
|
||||
|
||||
/// Curve defined using polynomial parameters
|
||||
///
|
||||
/// Most applications use a named EC_GROUP curve, however, support
|
||||
/// is included to explicitly define the curve used to calculate keys
|
||||
/// This information would need to be known by both endpoint to make communication
|
||||
/// effective.
|
||||
///
|
||||
/// OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1.
|
||||
/// Man page documents that 0 can be used in older versions.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP`]
|
||||
///
|
||||
/// [`EC_GROUP`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_seed_len.html
|
||||
pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0);
|
||||
|
||||
/// Standard Curves
|
||||
///
|
||||
/// Curves that make up the typical encryption use cases. The collection of curves
|
||||
/// are well known but extensible.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP`]
|
||||
///
|
||||
/// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/man3/EC_GROUP_order_bits.html
|
||||
pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE);
|
||||
use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
|
||||
use {cvt, cvt_n, cvt_p, init};
|
||||
|
||||
/// Compressed or Uncompressed conversion
|
||||
///
|
||||
@ -91,13 +55,53 @@ pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE);
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PointConversionForm(ffi::point_conversion_form_t);
|
||||
|
||||
impl PointConversionForm {
|
||||
/// Compressed conversion from point value.
|
||||
pub const COMPRESSED: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
/// Uncompressed conversion from point value.
|
||||
pub const UNCOMPRESSED: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED);
|
||||
|
||||
/// Performs both compressed and uncompressed conversions.
|
||||
pub const HYBRID: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID);
|
||||
}
|
||||
|
||||
/// Named Curve or Explicit
|
||||
///
|
||||
/// This type acts as a boolean as to whether the EC_Group is named or
|
||||
/// explicit.
|
||||
/// This type acts as a boolean as to whether the `EcGroup` is named or explicit.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Asn1Flag(c_int);
|
||||
|
||||
impl Asn1Flag {
|
||||
/// Curve defined using polynomial parameters
|
||||
///
|
||||
/// Most applications use a named EC_GROUP curve, however, support
|
||||
/// is included to explicitly define the curve used to calculate keys
|
||||
/// This information would need to be known by both endpoint to make communication
|
||||
/// effective.
|
||||
///
|
||||
/// OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1.
|
||||
/// Man page documents that 0 can be used in older versions.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP`]
|
||||
///
|
||||
/// [`EC_GROUP`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_seed_len.html
|
||||
pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0);
|
||||
|
||||
/// Standard Curves
|
||||
///
|
||||
/// Curves that make up the typical encryption use cases. The collection of curves
|
||||
/// are well known but extensible.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP`]
|
||||
///
|
||||
/// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/man3/EC_GROUP_order_bits.html
|
||||
pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE);
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::EC_GROUP;
|
||||
fn drop = ffi::EC_GROUP_free;
|
||||
@ -160,7 +164,8 @@ impl EcGroupRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +194,28 @@ impl EcGroupRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Places the cofactor of the group in the provided `BigNum`.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP_get_cofactor`]
|
||||
///
|
||||
/// [`EC_GROUP_get_cofactor`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_cofactor.html
|
||||
pub fn cofactor(
|
||||
&self,
|
||||
cofactor: &mut BigNumRef,
|
||||
ctx: &mut BigNumContextRef,
|
||||
) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_GROUP_get_cofactor(
|
||||
self.as_ptr(),
|
||||
cofactor.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,6 +228,18 @@ impl EcGroupRef {
|
||||
unsafe { ffi::EC_GROUP_get_degree(self.as_ptr()) as u32 }
|
||||
}
|
||||
|
||||
/// Returns the generator for the given curve as a [`EcPoint`].
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP_get0_generator`]
|
||||
///
|
||||
/// [`EC_GROUP_get0_generator`]: https://www.openssl.org/docs/man1.1.0/man3/EC_GROUP_get0_generator.html
|
||||
pub fn generator(&self) -> &EcPointRef {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_GROUP_get0_generator(self.as_ptr());
|
||||
EcPointRef::from_ptr(ptr as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
/// Places the order of the curve in the provided `BigNum`.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP_get_order`]
|
||||
@ -217,7 +255,8 @@ impl EcGroupRef {
|
||||
self.as_ptr(),
|
||||
order.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,6 +270,16 @@ impl EcGroupRef {
|
||||
ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name of the curve, if a name is associated.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_GROUP_get_curve_name`]
|
||||
///
|
||||
/// [`EC_GROUP_get_curve_name`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_curve_name.html
|
||||
pub fn curve_name(&self) -> Option<Nid> {
|
||||
let nid = unsafe { ffi::EC_GROUP_get_curve_name(self.as_ptr()) };
|
||||
if nid > 0 { Some(Nid::from_raw(nid)) } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
@ -269,7 +318,8 @@ impl EcPointRef {
|
||||
a.as_ptr(),
|
||||
b.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,11 +343,12 @@ impl EcPointRef {
|
||||
q.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes `generator * n`, storing the result ing `self`.
|
||||
/// Computes `generator * n`, storing the result in `self`.
|
||||
pub fn mul_generator(
|
||||
&mut self,
|
||||
group: &EcGroupRef,
|
||||
@ -312,7 +363,8 @@ impl EcPointRef {
|
||||
ptr::null(),
|
||||
ptr::null(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +385,8 @@ impl EcPointRef {
|
||||
q.as_ptr(),
|
||||
m.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +401,8 @@ impl EcPointRef {
|
||||
group.as_ptr(),
|
||||
self.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,6 +446,20 @@ impl EcPointRef {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new point on the specified curve with the same value.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_POINT_dup`]
|
||||
///
|
||||
/// [`EC_POINT_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_POINT_dup.html
|
||||
pub fn to_owned(
|
||||
&self,
|
||||
group: &EcGroupRef,
|
||||
) -> Result<EcPoint, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::EC_POINT_dup(self.as_ptr(), group.as_ptr())).map(EcPoint)
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if this point is equal to another.
|
||||
///
|
||||
/// OpenSSL doucmentation at [`EC_POINT_cmp`]
|
||||
@ -434,7 +502,8 @@ impl EcPointRef {
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +528,8 @@ impl EcPointRef {
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
ctx.as_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -498,7 +568,7 @@ impl EcPoint {
|
||||
}
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::EC_KEY;
|
||||
fn drop = ffi::EC_KEY_free;
|
||||
|
||||
@ -507,47 +577,46 @@ foreign_type_and_impl_send_sync! {
|
||||
/// OpenSSL documentation at [`EC_KEY_new`]
|
||||
///
|
||||
/// [`EC_KEY_new`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new.html
|
||||
pub struct EcKey;
|
||||
pub struct EcKey<T>;
|
||||
|
||||
/// Reference to [`EcKey`]
|
||||
///
|
||||
/// [`EcKey`]: struct.EcKey.html
|
||||
pub struct EcKeyRef;
|
||||
pub struct EcKeyRef<T>;
|
||||
}
|
||||
|
||||
impl EcKeyRef {
|
||||
private_key_to_pem!(ffi::PEM_write_bio_ECPrivateKey);
|
||||
private_key_to_der!(ffi::i2d_ECPrivateKey);
|
||||
|
||||
/// Return [`EcGroup`] of the `EcKey`
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_KEY_get0_group`]
|
||||
///
|
||||
/// [`EC_KEY_get0_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_group.html
|
||||
pub fn group(&self) -> Option<&EcGroupRef> {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_KEY_get0_group(self.as_ptr());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(EcGroupRef::from_ptr(ptr as *mut _))
|
||||
}
|
||||
}
|
||||
impl<T> EcKeyRef<T>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
private_key_to_pem! {
|
||||
/// Serializes the private key to a PEM-encoded ECPrivateKey structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_ECPrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_ECPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_ECPrivateKey.html
|
||||
private_key_to_pem,
|
||||
/// Serializes the private key to a PEM-encoded encrypted ECPrivateKey structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_ECPrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_ECPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_ECPrivateKey.html
|
||||
private_key_to_pem_passphrase,
|
||||
ffi::PEM_write_bio_ECPrivateKey
|
||||
}
|
||||
|
||||
/// Return [`EcPoint`] associated with the public key
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_KEY_get0_pubic_key`]
|
||||
///
|
||||
/// [`EC_KEY_get0_pubic_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_public_key.html
|
||||
pub fn public_key(&self) -> Option<&EcPointRef> {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_KEY_get0_public_key(self.as_ptr());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(EcPointRef::from_ptr(ptr as *mut _))
|
||||
}
|
||||
}
|
||||
to_der! {
|
||||
/// Serializes the private key into a DER-encoded ECPrivateKey structure.
|
||||
///
|
||||
/// This corresponds to [`i2d_ECPrivateKey`].
|
||||
///
|
||||
/// [`i2d_ECPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivate_key.html
|
||||
private_key_to_der,
|
||||
ffi::i2d_ECPrivateKey
|
||||
}
|
||||
|
||||
/// Return [`EcPoint`] associated with the private key
|
||||
@ -555,14 +624,44 @@ impl EcKeyRef {
|
||||
/// OpenSSL documentation at [`EC_KEY_get0_private_key`]
|
||||
///
|
||||
/// [`EC_KEY_get0_private_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_private_key.html
|
||||
pub fn private_key(&self) -> Option<&BigNumRef> {
|
||||
pub fn private_key(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_KEY_get0_private_key(self.as_ptr());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(BigNumRef::from_ptr(ptr as *mut _))
|
||||
}
|
||||
BigNumRef::from_ptr(ptr as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EcKeyRef<T>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
/// Returns the public key.
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_KEY_get0_pubic_key`]
|
||||
///
|
||||
/// [`EC_KEY_get0_pubic_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_public_key.html
|
||||
pub fn public_key(&self) -> &EcPointRef {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_KEY_get0_public_key(self.as_ptr());
|
||||
EcPointRef::from_ptr(ptr as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EcKeyRef<T>
|
||||
where
|
||||
T: HasParams,
|
||||
{
|
||||
/// Return [`EcGroup`] of the `EcKey`
|
||||
///
|
||||
/// OpenSSL documentation at [`EC_KEY_get0_group`]
|
||||
///
|
||||
/// [`EC_KEY_get0_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_group.html
|
||||
pub fn group(&self) -> &EcGroupRef {
|
||||
unsafe {
|
||||
let ptr = ffi::EC_KEY_get0_group(self.as_ptr());
|
||||
EcGroupRef::from_ptr(ptr as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,14 +673,21 @@ impl EcKeyRef {
|
||||
pub fn check_key(&self) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::EC_KEY_check_key(self.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a copy of the `EcKey` to allow modification
|
||||
pub fn to_owned(&self) -> Result<EcKey, ErrorStack> {
|
||||
unsafe { cvt_p(ffi::EC_KEY_dup(self.as_ptr())).map(EcKey) }
|
||||
impl<T> ToOwned for EcKeyRef<T> {
|
||||
type Owned = EcKey<T>;
|
||||
|
||||
fn to_owned(&self) -> EcKey<T> {
|
||||
unsafe {
|
||||
let r = ffi::EC_KEY_up_ref(self.as_ptr());
|
||||
assert!(r == 1);
|
||||
EcKey::from_ptr(self.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcKey {
|
||||
impl EcKey<Params> {
|
||||
/// Constructs an `EcKey` corresponding to a known curve.
|
||||
///
|
||||
/// It will not have an associated public or private key. This kind of key is primarily useful
|
||||
@ -590,13 +696,30 @@ impl EcKey {
|
||||
/// OpenSSL documenation at [`EC_KEY_new_by_curve_name`]
|
||||
///
|
||||
/// [`EC_KEY_new_by_curve_name`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new_by_curve_name.html
|
||||
pub fn from_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
|
||||
pub fn from_curve_name(nid: Nid) -> Result<EcKey<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
init();
|
||||
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey)
|
||||
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(|p| EcKey::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an `EcKey` corresponding to a curve.
|
||||
///
|
||||
/// This corresponds to [`EC_KEY_set_group`].
|
||||
///
|
||||
/// [`EC_KEY_set_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new.html
|
||||
pub fn from_group(group: &EcGroupRef) -> Result<EcKey<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::EC_KEY_new())
|
||||
.map(|p| EcKey::from_ptr(p))
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcKey<Public> {
|
||||
/// Constructs an `EcKey` from the specified group with the associated `EcPoint`, public_key.
|
||||
///
|
||||
/// This will only have the associated public_key.
|
||||
@ -606,14 +729,14 @@ impl EcKey {
|
||||
/// ```no_run
|
||||
/// use openssl::bn::BigNumContext;
|
||||
/// use openssl::ec::*;
|
||||
/// use openssl::nid;
|
||||
/// use openssl::nid::Nid;
|
||||
/// use openssl::pkey::PKey;
|
||||
///
|
||||
/// // get bytes from somewhere, i.e. this will not produce a valid key
|
||||
/// let public_key: Vec<u8> = vec![];
|
||||
///
|
||||
/// // create an EcKey from the binary form of a EcPoint
|
||||
/// let group = EcGroup::from_curve_name(nid::SECP256K1).unwrap();
|
||||
/// let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap();
|
||||
/// let mut ctx = BigNumContext::new().unwrap();
|
||||
/// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx).unwrap();
|
||||
/// let key = EcKey::from_public_key(&group, &point);
|
||||
@ -621,259 +744,289 @@ impl EcKey {
|
||||
pub fn from_public_key(
|
||||
group: &EcGroupRef,
|
||||
public_key: &EcPointRef,
|
||||
) -> Result<EcKey, ErrorStack> {
|
||||
let mut builder = EcKeyBuilder::new()?;
|
||||
builder.set_group(group)?;
|
||||
builder.set_public_key(public_key)?;
|
||||
Ok(builder.build())
|
||||
}
|
||||
|
||||
/// Generates a new public/private key pair on the specified curve.
|
||||
pub fn generate(group: &EcGroupRef) -> Result<EcKey, ErrorStack> {
|
||||
let mut builder = EcKeyBuilder::new()?;
|
||||
builder.set_group(group)?;
|
||||
builder.generate_key()?;
|
||||
Ok(builder.build())
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.2", note = "use from_curve_name")]
|
||||
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
|
||||
EcKey::from_curve_name(nid)
|
||||
}
|
||||
|
||||
private_key_from_pem!(EcKey, ffi::PEM_read_bio_ECPrivateKey);
|
||||
private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey);
|
||||
}
|
||||
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::EC_KEY;
|
||||
fn drop = ffi::EC_KEY_free;
|
||||
|
||||
/// Builder pattern for key generation
|
||||
///
|
||||
/// Returns a `EcKeyBuilder` to be consumed by `build`
|
||||
pub struct EcKeyBuilder;
|
||||
/// Reference to [`EcKeyBuilder`]
|
||||
///
|
||||
/// [`EcKeyBuilder`]: struct.EcKeyBuilder.html
|
||||
pub struct EcKeyBuilderRef;
|
||||
}
|
||||
|
||||
impl EcKeyBuilder {
|
||||
/// Creates an empty `EcKeyBuilder` to be chained with additonal methods
|
||||
pub fn new() -> Result<EcKeyBuilder, ErrorStack> {
|
||||
) -> Result<EcKey<Public>, ErrorStack> {
|
||||
unsafe {
|
||||
init();
|
||||
cvt_p(ffi::EC_KEY_new()).map(EcKeyBuilder)
|
||||
cvt_p(ffi::EC_KEY_new())
|
||||
.map(|p| EcKey::from_ptr(p))
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
|
||||
})
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_public_key(
|
||||
key.as_ptr(),
|
||||
public_key.as_ptr(),
|
||||
))
|
||||
.map(|_| key)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume the `EcKeyBuilder` and return [`EcKey`]
|
||||
///
|
||||
/// [`EcKey`]: struct.EcKey.html
|
||||
pub fn build(self) -> EcKey {
|
||||
unsafe {
|
||||
let key = EcKey::from_ptr(self.as_ptr());
|
||||
mem::forget(self);
|
||||
key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcKeyBuilderRef {
|
||||
/// Set the [`EcGroup`] explicitly
|
||||
///
|
||||
/// [`EcGroup`]: struct.EcGroup.html
|
||||
pub fn set_group(&mut self, group: &EcGroupRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe { cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self) }
|
||||
}
|
||||
|
||||
/// Set public key to given `EcPoint`
|
||||
pub fn set_public_key(
|
||||
&mut self,
|
||||
public_key: &EcPointRef,
|
||||
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_KEY_set_public_key(
|
||||
self.as_ptr(),
|
||||
public_key.as_ptr(),
|
||||
)).map(|_| self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate public and private keys.
|
||||
pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) }
|
||||
}
|
||||
|
||||
/// Sets the public key based on affine coordinates.
|
||||
pub fn set_public_key_affine_coordinates(
|
||||
&mut self,
|
||||
/// Constructs a public key from its affine coordinates.
|
||||
pub fn from_public_key_affine_coordinates(
|
||||
group: &EcGroupRef,
|
||||
x: &BigNumRef,
|
||||
y: &BigNumRef,
|
||||
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
) -> Result<EcKey<Public>, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(
|
||||
self.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
)).map(|_| self)
|
||||
cvt_p(ffi::EC_KEY_new())
|
||||
.map(|p| EcKey::from_ptr(p))
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
|
||||
})
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(
|
||||
key.as_ptr(),
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
))
|
||||
.map(|_| key)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcKey<Private> {
|
||||
/// Generates a new public/private key pair on the specified curve.
|
||||
pub fn generate(group: &EcGroupRef) -> Result<EcKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::EC_KEY_new())
|
||||
.map(|p| EcKey::from_ptr(p))
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
|
||||
})
|
||||
.and_then(|key| cvt(ffi::EC_KEY_generate_key(key.as_ptr())).map(|_| key))
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the private key.
|
||||
pub fn set_private_key(&mut self, key: &BigNumRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
|
||||
unsafe { cvt(ffi::EC_KEY_set_private_key(self.as_ptr(), key.as_ptr())).map(|_| self) }
|
||||
/// Constructs an public/private key pair given a curve, a private key and a public key point.
|
||||
pub fn from_private_components(
|
||||
group: &EcGroupRef,
|
||||
private_number: &BigNumRef,
|
||||
public_key: &EcPointRef,
|
||||
) -> Result<EcKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::EC_KEY_new())
|
||||
.map(|p| EcKey::from_ptr(p))
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
|
||||
})
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_private_key(
|
||||
key.as_ptr(),
|
||||
private_number.as_ptr(),
|
||||
))
|
||||
.map(|_| key)
|
||||
})
|
||||
.and_then(|key| {
|
||||
cvt(ffi::EC_KEY_set_public_key(
|
||||
key.as_ptr(),
|
||||
public_key.as_ptr(),
|
||||
))
|
||||
.map(|_| key)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private_key_from_pem! {
|
||||
/// Deserializes a private key from a PEM-encoded ECPrivateKey structure.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
|
||||
private_key_from_pem,
|
||||
|
||||
/// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
|
||||
private_key_from_pem_passphrase,
|
||||
|
||||
/// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure.
|
||||
///
|
||||
/// The callback should fill the password into the provided buffer and return its length.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
|
||||
private_key_from_pem_callback,
|
||||
EcKey<Private>,
|
||||
ffi::PEM_read_bio_ECPrivateKey
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Decodes a DER-encoded elliptic curve private key structure.
|
||||
///
|
||||
/// This corresponds to [`d2i_ECPrivateKey`].
|
||||
///
|
||||
/// [`d2i_ECPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivate_key.html
|
||||
private_key_from_der,
|
||||
EcKey<Private>,
|
||||
ffi::d2i_ECPrivateKey
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for EcKey<T> {
|
||||
fn clone(&self) -> EcKey<T> {
|
||||
(**self).to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for EcKey<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "EcKey")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use bn::{BigNum, BigNumContext};
|
||||
use nid;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use hex::FromHex;
|
||||
|
||||
use super::*;
|
||||
use bn::{BigNum, BigNumContext};
|
||||
use nid::Nid;
|
||||
|
||||
#[test]
|
||||
fn key_new_by_curve_name() {
|
||||
EcKey::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
key.public_key().unwrap();
|
||||
key.private_key().unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
EcKey::generate(&group).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cofactor() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let mut cofactor = BigNum::new().unwrap();
|
||||
group.cofactor(&mut cofactor, &mut ctx).unwrap();
|
||||
let one = BigNum::from_u32(1).unwrap();
|
||||
assert_eq!(cofactor, one);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dup() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
key.to_owned().unwrap();
|
||||
drop(key.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn point_new() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
EcPoint::new(&group).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn point_bytes() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
let point = key.public_key().unwrap();
|
||||
let point = key.public_key();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let bytes = point
|
||||
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
|
||||
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
|
||||
.unwrap();
|
||||
let point2 = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
|
||||
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn point_owned() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
let point = key.public_key();
|
||||
let owned = point.to_owned(&group).unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
assert!(owned.eq(&group, point, &mut ctx).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul_generator() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let mut public_key = EcPoint::new(&group).unwrap();
|
||||
public_key
|
||||
.mul_generator(&group, key.private_key().unwrap(), &mut ctx)
|
||||
.mul_generator(&group, key.private_key(), &mut ctx)
|
||||
.unwrap();
|
||||
assert!(
|
||||
public_key
|
||||
.eq(&group, key.public_key().unwrap(), &mut ctx)
|
||||
.unwrap()
|
||||
);
|
||||
assert!(public_key.eq(&group, key.public_key(), &mut ctx).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generator() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let gen = group.generator();
|
||||
let one = BigNum::from_u32(1).unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let mut ecp = EcPoint::new(&group).unwrap();
|
||||
ecp.mul_generator(&group, &one, &mut ctx).unwrap();
|
||||
assert!(ecp.eq(&group, gen, &mut ctx).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_from_public_key() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let bytes = key.public_key()
|
||||
.unwrap()
|
||||
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
|
||||
let bytes = key
|
||||
.public_key()
|
||||
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
|
||||
.unwrap();
|
||||
|
||||
drop(key);
|
||||
let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
|
||||
let ec_key = EcKey::from_public_key(&group, &public_key).unwrap();
|
||||
assert!(ec_key.check_key().is_ok());
|
||||
assert!(ec_key.public_key().is_some());
|
||||
assert!(ec_key.private_key().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_from_private_components() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
|
||||
let dup_key =
|
||||
EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
|
||||
let res = dup_key.check_key().unwrap();
|
||||
|
||||
assert!(res == ());
|
||||
assert!(key.private_key() == dup_key.private_key());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_from_affine_coordinates() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = BASE64URL_NOPAD.decode(
|
||||
"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes(),
|
||||
).unwrap();
|
||||
let y = BASE64URL_NOPAD.decode(
|
||||
"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes(),
|
||||
).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e")
|
||||
.unwrap();
|
||||
let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723")
|
||||
.unwrap();
|
||||
|
||||
let xbn = BigNum::from_slice(&x).unwrap();
|
||||
let ybn = BigNum::from_slice(&y).unwrap();
|
||||
|
||||
let mut builder = EcKeyBuilder::new().unwrap();
|
||||
builder.set_group(&group).unwrap();
|
||||
builder
|
||||
.set_public_key_affine_coordinates(&xbn, &ybn)
|
||||
.unwrap();
|
||||
|
||||
let ec_key = builder.build();
|
||||
let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap();
|
||||
assert!(ec_key.check_key().is_ok());
|
||||
assert!(ec_key.public_key().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_private_key() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let d = BASE64URL_NOPAD.decode(
|
||||
"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE".as_bytes(),
|
||||
).unwrap();
|
||||
|
||||
let dbn = BigNum::from_slice(&d).unwrap();
|
||||
|
||||
let mut builder = EcKeyBuilder::new().unwrap();
|
||||
builder.set_group(&group).unwrap();
|
||||
builder.set_private_key(&dbn).unwrap();
|
||||
|
||||
let ec_key = builder.build();
|
||||
assert!(ec_key.private_key().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_affine_coordinates() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = BASE64URL_NOPAD.decode(
|
||||
"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes(),
|
||||
).unwrap();
|
||||
let y = BASE64URL_NOPAD.decode(
|
||||
"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes(),
|
||||
).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e")
|
||||
.unwrap();
|
||||
let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723")
|
||||
.unwrap();
|
||||
|
||||
let xbn = BigNum::from_slice(&x).unwrap();
|
||||
let ybn = BigNum::from_slice(&y).unwrap();
|
||||
|
||||
let mut builder = EcKeyBuilder::new().unwrap();
|
||||
builder.set_group(&group).unwrap();
|
||||
builder
|
||||
.set_public_key_affine_coordinates(&xbn, &ybn)
|
||||
.unwrap();
|
||||
|
||||
let ec_key = builder.build();
|
||||
let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap();
|
||||
|
||||
let mut xbn2 = BigNum::new().unwrap();
|
||||
let mut ybn2 = BigNum::new().unwrap();
|
||||
let mut ctx = BigNumContext::new().unwrap();
|
||||
let ec_key_pk = ec_key.public_key().unwrap();
|
||||
let ec_key_pk = ec_key.public_key();
|
||||
ec_key_pk
|
||||
.affine_coordinates_gfp(&group, &mut xbn2, &mut ybn2, &mut ctx)
|
||||
.unwrap();
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#![doc(hidden)]
|
||||
#![deprecated(since = "0.9.2", note = "renamed to `ec`")]
|
||||
|
||||
pub use ec::{EcKey, EcKeyRef};
|
||||
243
openssl/src/ecdsa.rs
Normal file
243
openssl/src/ecdsa.rs
Normal file
@ -0,0 +1,243 @@
|
||||
//! Low level Elliptic Curve Digital Signature Algorithm (ECDSA) functions.
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use bn::{BigNum, BigNumRef};
|
||||
use ec::EcKeyRef;
|
||||
use error::ErrorStack;
|
||||
use pkey::{Private, Public};
|
||||
use {cvt_n, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::ECDSA_SIG;
|
||||
fn drop = ffi::ECDSA_SIG_free;
|
||||
|
||||
/// A low level interface to ECDSA
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_sign`]
|
||||
///
|
||||
/// [`ECDSA_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_sign.html
|
||||
pub struct EcdsaSig;
|
||||
/// Reference to [`EcdsaSig`]
|
||||
///
|
||||
/// [`EcdsaSig`]: struct.EcdsaSig.html
|
||||
pub struct EcdsaSigRef;
|
||||
}
|
||||
|
||||
impl EcdsaSig {
|
||||
/// Computes a digital signature of the hash value `data` using the private EC key eckey.
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_do_sign`]
|
||||
///
|
||||
/// [`ECDSA_do_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_do_sign.html
|
||||
pub fn sign(data: &[u8], eckey: &EcKeyRef<Private>) -> Result<EcdsaSig, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(data.len() <= c_int::max_value() as usize);
|
||||
let sig = cvt_p(ffi::ECDSA_do_sign(
|
||||
data.as_ptr(),
|
||||
data.len() as c_int,
|
||||
eckey.as_ptr(),
|
||||
))?;
|
||||
Ok(EcdsaSig::from_ptr(sig as *mut _))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new `EcdsaSig` by setting the `r` and `s` values associated with a
|
||||
/// ECDSA signature.
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_SIG_set0`]
|
||||
///
|
||||
/// [`ECDSA_SIG_set0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_set0.html
|
||||
pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
|
||||
unsafe {
|
||||
let sig = cvt_p(ffi::ECDSA_SIG_new())?;
|
||||
ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
|
||||
mem::forget((r, s));
|
||||
Ok(EcdsaSig::from_ptr(sig as *mut _))
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifies if the signature is a valid ECDSA signature using the given public key.
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_do_verify`]
|
||||
///
|
||||
/// [`ECDSA_do_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_do_verify.html
|
||||
pub fn verify(&self, data: &[u8], eckey: &EcKeyRef<Public>) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(data.len() <= c_int::max_value() as usize);
|
||||
cvt_n(ffi::ECDSA_do_verify(
|
||||
data.as_ptr(),
|
||||
data.len() as c_int,
|
||||
self.as_ptr(),
|
||||
eckey.as_ptr(),
|
||||
))
|
||||
.map(|x| x == 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns internal component: `r` of a `EcdsaSig`. (See X9.62 or FIPS 186-2)
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_SIG_get0`]
|
||||
///
|
||||
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
|
||||
pub fn r(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let mut r = ptr::null();
|
||||
ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
|
||||
BigNumRef::from_ptr(r as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns internal components: `s` of a `EcdsaSig`. (See X9.62 or FIPS 186-2)
|
||||
///
|
||||
/// OpenSSL documentation at [`ECDSA_SIG_get0`]
|
||||
///
|
||||
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
|
||||
pub fn s(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let mut s = ptr::null();
|
||||
ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
|
||||
BigNumRef::from_ptr(s as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Decodes a DER-encoded ECDSA signature.
|
||||
///
|
||||
/// This corresponds to [`d2i_ECDSA_SIG`].
|
||||
///
|
||||
/// [`d2i_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_ECDSA_SIG.html
|
||||
from_der,
|
||||
EcdsaSig,
|
||||
ffi::d2i_ECDSA_SIG
|
||||
}
|
||||
}
|
||||
|
||||
impl EcdsaSigRef {
|
||||
to_der! {
|
||||
/// Serializes the ECDSA signature into a DER-encoded ECDSASignature structure.
|
||||
///
|
||||
/// This corresponds to [`i2d_ECDSA_SIG`].
|
||||
///
|
||||
/// [`i2d_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_ECDSA_SIG.html
|
||||
to_der,
|
||||
ffi::i2d_ECDSA_SIG
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ECDSA_SIG_set0(
|
||||
sig: *mut ffi::ECDSA_SIG,
|
||||
r: *mut ffi::BIGNUM,
|
||||
s: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
if r.is_null() || s.is_null() {
|
||||
return 0;
|
||||
}
|
||||
ffi::BN_clear_free((*sig).r);
|
||||
ffi::BN_clear_free((*sig).s);
|
||||
(*sig).r = r;
|
||||
(*sig).s = s;
|
||||
1
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ECDSA_SIG_get0(
|
||||
sig: *const ffi::ECDSA_SIG,
|
||||
pr: *mut *const ffi::BIGNUM,
|
||||
ps: *mut *const ffi::BIGNUM)
|
||||
{
|
||||
if !pr.is_null() {
|
||||
(*pr) = (*sig).r;
|
||||
}
|
||||
if !ps.is_null() {
|
||||
(*ps) = (*sig).s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use ec::EcGroup;
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
|
||||
fn get_public_key(group: &EcGroup, x: &EcKey<Private>) -> Result<EcKey<Public>, ErrorStack> {
|
||||
let public_key_point = x.public_key();
|
||||
Ok(EcKey::from_public_key(group, public_key_point)?)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
|
||||
fn sign_and_verify() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap();
|
||||
let private_key = EcKey::generate(&group).unwrap();
|
||||
let public_key = get_public_key(&group, &private_key).unwrap();
|
||||
|
||||
let private_key2 = EcKey::generate(&group).unwrap();
|
||||
let public_key2 = get_public_key(&group, &private_key2).unwrap();
|
||||
|
||||
let data = String::from("hello");
|
||||
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
|
||||
|
||||
// Signature can be verified using the correct data & correct public key
|
||||
let verification = res.verify(data.as_bytes(), &public_key).unwrap();
|
||||
assert!(verification);
|
||||
|
||||
// Signature will not be verified using the incorrect data but the correct public key
|
||||
let verification2 = res
|
||||
.verify(String::from("hello2").as_bytes(), &public_key)
|
||||
.unwrap();
|
||||
assert!(verification2 == false);
|
||||
|
||||
// Signature will not be verified using the correct data but the incorrect public key
|
||||
let verification3 = res.verify(data.as_bytes(), &public_key2).unwrap();
|
||||
assert!(verification3 == false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
|
||||
fn check_private_components() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap();
|
||||
let private_key = EcKey::generate(&group).unwrap();
|
||||
let public_key = get_public_key(&group, &private_key).unwrap();
|
||||
let data = String::from("hello");
|
||||
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
|
||||
|
||||
let verification = res.verify(data.as_bytes(), &public_key).unwrap();
|
||||
assert!(verification);
|
||||
|
||||
let r = res.r().to_owned().unwrap();
|
||||
let s = res.s().to_owned().unwrap();
|
||||
|
||||
let res2 = EcdsaSig::from_private_components(r, s).unwrap();
|
||||
let verification2 = res2.verify(data.as_bytes(), &public_key).unwrap();
|
||||
assert!(verification2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
|
||||
fn serialize_deserialize() {
|
||||
let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap();
|
||||
let private_key = EcKey::generate(&group).unwrap();
|
||||
let public_key = get_public_key(&group, &private_key).unwrap();
|
||||
|
||||
let data = String::from("hello");
|
||||
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
|
||||
|
||||
let der = res.to_der().unwrap();
|
||||
let sig = EcdsaSig::from_der(&der).unwrap();
|
||||
|
||||
let verification = sig.verify(data.as_bytes(), &public_key).unwrap();
|
||||
assert!(verification);
|
||||
}
|
||||
}
|
||||
282
openssl/src/envelope.rs
Normal file
282
openssl/src/envelope.rs
Normal file
@ -0,0 +1,282 @@
|
||||
//! Envelope encryption.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```rust
|
||||
//!
|
||||
//! extern crate openssl;
|
||||
//!
|
||||
//! use openssl::rsa::Rsa;
|
||||
//! use openssl::envelope::Seal;
|
||||
//! use openssl::pkey::PKey;
|
||||
//! use openssl::symm::Cipher;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let rsa = Rsa::generate(2048).unwrap();
|
||||
//! let key = PKey::from_rsa(rsa).unwrap();
|
||||
//!
|
||||
//! let cipher = Cipher::aes_256_cbc();
|
||||
//! let mut seal = Seal::new(cipher, &[key]).unwrap();
|
||||
//!
|
||||
//! let secret = b"My secret message";
|
||||
//! let mut encrypted = vec![0; secret.len() + cipher.block_size()];
|
||||
//!
|
||||
//! let mut enc_len = seal.update(secret, &mut encrypted).unwrap();
|
||||
//! enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap();
|
||||
//! encrypted.truncate(enc_len);
|
||||
//! }
|
||||
//! ```
|
||||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
|
||||
use std::cmp;
|
||||
use std::ptr;
|
||||
use symm::Cipher;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
/// Represents an EVP_Seal context.
|
||||
pub struct Seal {
|
||||
ctx: *mut ffi::EVP_CIPHER_CTX,
|
||||
block_size: usize,
|
||||
iv: Option<Vec<u8>>,
|
||||
enc_keys: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Seal {
|
||||
/// Creates a new `Seal`.
|
||||
pub fn new<T>(cipher: Cipher, pub_keys: &[PKey<T>]) -> Result<Seal, ErrorStack>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
unsafe {
|
||||
assert!(pub_keys.len() <= c_int::max_value() as usize);
|
||||
|
||||
let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
|
||||
let mut enc_key_ptrs = vec![];
|
||||
let mut pub_key_ptrs = vec![];
|
||||
let mut enc_keys = vec![];
|
||||
for key in pub_keys {
|
||||
let mut enc_key = vec![0; key.size()];
|
||||
let enc_key_ptr = enc_key.as_mut_ptr();
|
||||
enc_keys.push(enc_key);
|
||||
enc_key_ptrs.push(enc_key_ptr);
|
||||
pub_key_ptrs.push(key.as_ptr());
|
||||
}
|
||||
let mut iv = cipher.iv_len().map(|len| Vec::with_capacity(len));
|
||||
let iv_ptr = iv.as_mut().map_or(ptr::null_mut(), |v| v.as_mut_ptr());
|
||||
let mut enc_key_lens = vec![0; enc_keys.len()];
|
||||
|
||||
cvt(ffi::EVP_SealInit(
|
||||
ctx,
|
||||
cipher.as_ptr(),
|
||||
enc_key_ptrs.as_mut_ptr(),
|
||||
enc_key_lens.as_mut_ptr(),
|
||||
iv_ptr,
|
||||
pub_key_ptrs.as_mut_ptr(),
|
||||
pub_key_ptrs.len() as c_int,
|
||||
))?;
|
||||
|
||||
for (buf, len) in enc_keys.iter_mut().zip(&enc_key_lens) {
|
||||
buf.truncate(*len as usize);
|
||||
}
|
||||
|
||||
Ok(Seal {
|
||||
ctx,
|
||||
block_size: cipher.block_size(),
|
||||
iv,
|
||||
enc_keys,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the initialization vector, if the cipher uses one.
|
||||
pub fn iv(&self) -> Option<&[u8]> {
|
||||
self.iv.as_ref().map(|v| &**v)
|
||||
}
|
||||
|
||||
/// Returns the encrypted keys.
|
||||
pub fn encrypted_keys(&self) -> &[Vec<u8>] {
|
||||
&self.enc_keys
|
||||
}
|
||||
|
||||
/// Feeds data from `input` through the cipher, writing encrypted bytes into `output`.
|
||||
///
|
||||
/// The number of bytes written to `output` is returned. Note that this may
|
||||
/// not be equal to the length of `input`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `output.len() < input.len() + block_size` where `block_size` is
|
||||
/// the block size of the cipher (see `Cipher::block_size`), or if
|
||||
/// `output.len() > c_int::max_value()`.
|
||||
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(output.len() >= input.len() + self.block_size);
|
||||
assert!(output.len() <= c_int::max_value() as usize);
|
||||
let mut outl = output.len() as c_int;
|
||||
let inl = input.len() as c_int;
|
||||
cvt(ffi::EVP_EncryptUpdate(
|
||||
self.ctx,
|
||||
output.as_mut_ptr(),
|
||||
&mut outl,
|
||||
input.as_ptr(),
|
||||
inl,
|
||||
))?;
|
||||
Ok(outl as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Finishes the encryption process, writing any remaining data to `output`.
|
||||
///
|
||||
/// The number of bytes written to `output` is returned.
|
||||
///
|
||||
/// `update` should not be called after this method.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `output` is less than the cipher's block size.
|
||||
pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(output.len() >= self.block_size);
|
||||
let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
|
||||
|
||||
cvt(ffi::EVP_SealFinal(self.ctx, output.as_mut_ptr(), &mut outl))?;
|
||||
|
||||
Ok(outl as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Seal {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::EVP_CIPHER_CTX_free(self.ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an EVP_Open context.
|
||||
pub struct Open {
|
||||
ctx: *mut ffi::EVP_CIPHER_CTX,
|
||||
block_size: usize,
|
||||
}
|
||||
|
||||
impl Open {
|
||||
/// Creates a new `Open`.
|
||||
pub fn new<T>(
|
||||
cipher: Cipher,
|
||||
priv_key: &PKeyRef<T>,
|
||||
iv: Option<&[u8]>,
|
||||
encrypted_key: &[u8],
|
||||
) -> Result<Open, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
assert!(encrypted_key.len() <= c_int::max_value() as usize);
|
||||
assert!(cipher.iv_len().is_none() || iv.is_some());
|
||||
|
||||
let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
|
||||
cvt(ffi::EVP_OpenInit(
|
||||
ctx,
|
||||
cipher.as_ptr(),
|
||||
encrypted_key.as_ptr(),
|
||||
encrypted_key.len() as c_int,
|
||||
iv.map_or(ptr::null(), |v| v.as_ptr()),
|
||||
priv_key.as_ptr(),
|
||||
))?;
|
||||
Ok(Open {
|
||||
ctx,
|
||||
block_size: cipher.block_size(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Feeds data from `input` through the cipher, writing decrypted bytes into `output`.
|
||||
///
|
||||
/// The number of bytes written to `output` is returned. Note that this may
|
||||
/// not be equal to the length of `input`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `output.len() < input.len() + block_size` where
|
||||
/// `block_size` is the block size of the cipher (see `Cipher::block_size`),
|
||||
/// or if `output.len() > c_int::max_value()`.
|
||||
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(output.len() >= input.len() + self.block_size);
|
||||
assert!(output.len() <= c_int::max_value() as usize);
|
||||
let mut outl = output.len() as c_int;
|
||||
let inl = input.len() as c_int;
|
||||
cvt(ffi::EVP_DecryptUpdate(
|
||||
self.ctx,
|
||||
output.as_mut_ptr(),
|
||||
&mut outl,
|
||||
input.as_ptr(),
|
||||
inl,
|
||||
))?;
|
||||
Ok(outl as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Finishes the decryption process, writing any remaining data to `output`.
|
||||
///
|
||||
/// The number of bytes written to `output` is returned.
|
||||
///
|
||||
/// `update` should not be called after this method.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `output` is less than the cipher's block size.
|
||||
pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(output.len() >= self.block_size);
|
||||
let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
|
||||
|
||||
cvt(ffi::EVP_OpenFinal(self.ctx, output.as_mut_ptr(), &mut outl))?;
|
||||
|
||||
Ok(outl as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Open {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::EVP_CIPHER_CTX_free(self.ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use pkey::PKey;
|
||||
use symm::Cipher;
|
||||
|
||||
#[test]
|
||||
fn public_encrypt_private_decrypt() {
|
||||
let private_pem = include_bytes!("../test/rsa.pem");
|
||||
let public_pem = include_bytes!("../test/rsa.pem.pub");
|
||||
let private_key = PKey::private_key_from_pem(private_pem).unwrap();
|
||||
let public_key = PKey::public_key_from_pem(public_pem).unwrap();
|
||||
let cipher = Cipher::aes_256_cbc();
|
||||
let secret = b"My secret message";
|
||||
|
||||
let mut seal = Seal::new(cipher, &[public_key]).unwrap();
|
||||
let mut encrypted = vec![0; secret.len() + cipher.block_size()];
|
||||
let mut enc_len = seal.update(secret, &mut encrypted).unwrap();
|
||||
enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap();
|
||||
let iv = seal.iv();
|
||||
let encrypted_key = &seal.encrypted_keys()[0];
|
||||
|
||||
let mut open = Open::new(cipher, &private_key, iv, &encrypted_key).unwrap();
|
||||
let mut decrypted = vec![0; enc_len + cipher.block_size()];
|
||||
let mut dec_len = open.update(&encrypted[..enc_len], &mut decrypted).unwrap();
|
||||
dec_len += open.finalize(&mut decrypted[dec_len..]).unwrap();
|
||||
|
||||
assert_eq!(&secret[..], &decrypted[..dec_len]);
|
||||
}
|
||||
}
|
||||
@ -15,14 +15,14 @@
|
||||
//! Err(e) => println!("Parsing Error: {:?}", e),
|
||||
//! }
|
||||
//! ```
|
||||
use libc::{c_ulong, c_char, c_int};
|
||||
use std::fmt;
|
||||
use libc::{c_char, c_int, c_ulong};
|
||||
use std::borrow::Cow;
|
||||
use std::error;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::str;
|
||||
use std::ptr;
|
||||
use std::borrow::Cow;
|
||||
use std::str;
|
||||
|
||||
use ffi;
|
||||
|
||||
@ -41,6 +41,13 @@ impl ErrorStack {
|
||||
}
|
||||
ErrorStack(vec)
|
||||
}
|
||||
|
||||
/// Pushes the errors back onto the OpenSSL error stack.
|
||||
pub fn put(&self) {
|
||||
for error in self.errors() {
|
||||
error.put();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorStack {
|
||||
@ -52,6 +59,10 @@ impl ErrorStack {
|
||||
|
||||
impl fmt::Display for ErrorStack {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.0.is_empty() {
|
||||
return fmt.write_str("OpenSSL error");
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
for err in &self.0 {
|
||||
if !first {
|
||||
@ -122,16 +133,50 @@ impl Error {
|
||||
None
|
||||
};
|
||||
Some(Error {
|
||||
code: code,
|
||||
file: file,
|
||||
line: line,
|
||||
data: data,
|
||||
code,
|
||||
file,
|
||||
line,
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes the error back onto the OpenSSL error stack.
|
||||
pub fn put(&self) {
|
||||
unsafe {
|
||||
ffi::ERR_put_error(
|
||||
ffi::ERR_GET_LIB(self.code),
|
||||
ffi::ERR_GET_FUNC(self.code),
|
||||
ffi::ERR_GET_REASON(self.code),
|
||||
self.file,
|
||||
self.line,
|
||||
);
|
||||
let data = match self.data {
|
||||
Some(Cow::Borrowed(data)) => Some((data.as_ptr() as *mut c_char, 0)),
|
||||
Some(Cow::Owned(ref data)) => {
|
||||
let ptr = ffi::CRYPTO_malloc(
|
||||
(data.len() + 1) as _,
|
||||
concat!(file!(), "\0").as_ptr() as _,
|
||||
line!() as _,
|
||||
) as *mut c_char;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len());
|
||||
*ptr.offset(data.len() as isize) = 0;
|
||||
Some((ptr, ffi::ERR_TXT_MALLOCED))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
if let Some((ptr, flags)) = data {
|
||||
ffi::ERR_set_error_data(ptr, flags | ffi::ERR_TXT_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the raw OpenSSL error code for this error.
|
||||
pub fn code(&self) -> c_ulong {
|
||||
self.code
|
||||
@ -183,8 +228,8 @@ impl Error {
|
||||
}
|
||||
|
||||
/// Returns the line in the source file which encountered the error.
|
||||
pub fn line(&self) -> c_int {
|
||||
self.line
|
||||
pub fn line(&self) -> u32 {
|
||||
self.line as u32
|
||||
}
|
||||
|
||||
/// Returns additional data describing the error.
|
||||
@ -228,7 +273,7 @@ impl fmt::Display for Error {
|
||||
}
|
||||
match self.reason() {
|
||||
Some(r) => write!(fmt, ":{}", r)?,
|
||||
None => write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.code()))?,
|
||||
None => write!(fmt, ":reason({})", ffi::ERR_GET_REASON(self.code()))?,
|
||||
}
|
||||
write!(
|
||||
fmt,
|
||||
|
||||
22
openssl/src/fips.rs
Normal file
22
openssl/src/fips.rs
Normal file
@ -0,0 +1,22 @@
|
||||
//! FIPS 140-2 support.
|
||||
//!
|
||||
//! See [OpenSSL's documentation] for details.
|
||||
//!
|
||||
//! [OpenSSL's documentation]: https://www.openssl.org/docs/fips/UserGuide-2.0.pdf
|
||||
use cvt;
|
||||
use error::ErrorStack;
|
||||
use ffi;
|
||||
|
||||
/// Moves the library into or out of the FIPS 140-2 mode of operation.
|
||||
///
|
||||
/// This corresponds to `FIPS_mode_set`.
|
||||
pub fn enable(enabled: bool) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::FIPS_mode_set(enabled as _)).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Determines if the library is running in the FIPS 140-2 mode of operation.
|
||||
///
|
||||
/// This corresponds to `FIPS_mode`.
|
||||
pub fn enabled() -> bool {
|
||||
unsafe { ffi::FIPS_mode() != 0 }
|
||||
}
|
||||
@ -1,21 +1,45 @@
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::fmt;
|
||||
use ffi;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
} else {
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct MessageDigest(*const ffi::EVP_MD);
|
||||
|
||||
impl MessageDigest {
|
||||
pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self {
|
||||
MessageDigest(x)
|
||||
}
|
||||
|
||||
/// Returns the `MessageDigest` corresponding to an `Nid`.
|
||||
///
|
||||
/// This corresponds to [`EVP_get_digestbynid`].
|
||||
///
|
||||
/// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html
|
||||
pub fn from_nid(type_: Nid) -> Option<MessageDigest> {
|
||||
unsafe {
|
||||
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(MessageDigest(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn md5() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_md5()) }
|
||||
}
|
||||
@ -40,6 +64,36 @@ impl MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_sha512()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn sha3_224() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_sha3_224()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn sha3_256() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_sha3_256()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn sha3_384() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_sha3_384()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn sha3_512() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_sha3_512()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn shake_128() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_shake128()) }
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub fn shake_256() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_shake256()) }
|
||||
}
|
||||
|
||||
pub fn ripemd160() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_ripemd160()) }
|
||||
}
|
||||
@ -47,8 +101,21 @@ impl MessageDigest {
|
||||
pub fn as_ptr(&self) -> *const ffi::EVP_MD {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// The size of the digest in bytes
|
||||
pub fn size(&self) -> usize {
|
||||
unsafe { ffi::EVP_MD_size(self.0) as usize }
|
||||
}
|
||||
|
||||
/// The name of the digest
|
||||
pub fn type_(&self) -> Nid {
|
||||
Nid::from_raw(unsafe { ffi::EVP_MD_type(self.0) })
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for MessageDigest {}
|
||||
unsafe impl Send for MessageDigest {}
|
||||
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
enum State {
|
||||
Reset,
|
||||
@ -70,7 +137,7 @@ use self::State::*;
|
||||
/// let data = b"\x42\xF4\x97\xE0";
|
||||
/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2";
|
||||
/// let res = hash(MessageDigest::md5(), data).unwrap();
|
||||
/// assert_eq!(res, spec);
|
||||
/// assert_eq!(&*res, spec);
|
||||
/// ```
|
||||
///
|
||||
/// Supply the input in chunks:
|
||||
@ -84,7 +151,22 @@ use self::State::*;
|
||||
/// h.update(data[0]).unwrap();
|
||||
/// h.update(data[1]).unwrap();
|
||||
/// let res = h.finish().unwrap();
|
||||
/// assert_eq!(res, spec);
|
||||
/// assert_eq!(&*res, spec);
|
||||
/// ```
|
||||
///
|
||||
/// Use an XOF hasher (OpenSSL 1.1.1+):
|
||||
///
|
||||
/// ```
|
||||
/// #[cfg(ossl111)]
|
||||
/// {
|
||||
/// use openssl::hash::{hash_xof, MessageDigest};
|
||||
///
|
||||
/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73";
|
||||
/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35";
|
||||
/// let mut buf = vec![0; 16];
|
||||
/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap();
|
||||
/// assert_eq!(buf, spec);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Warning
|
||||
@ -92,6 +174,9 @@ use self::State::*;
|
||||
/// Don't actually use MD5 and SHA-1 hashes, they're not secure anymore.
|
||||
///
|
||||
/// Don't ever hash passwords, use the functions in the `pkcs5` module or bcrypt/scrypt instead.
|
||||
///
|
||||
/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), you must use finish_xof instead
|
||||
/// of finish and provide a buf to store the hash. The hash will be as long as the buf.
|
||||
pub struct Hasher {
|
||||
ctx: *mut ffi::EVP_MD_CTX,
|
||||
md: *const ffi::EVP_MD,
|
||||
@ -99,6 +184,9 @@ pub struct Hasher {
|
||||
state: State,
|
||||
}
|
||||
|
||||
unsafe impl Sync for Hasher {}
|
||||
unsafe impl Send for Hasher {}
|
||||
|
||||
impl Hasher {
|
||||
/// Creates a new `Hasher` with the specified hash type.
|
||||
pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> {
|
||||
@ -120,7 +208,7 @@ impl Hasher {
|
||||
match self.state {
|
||||
Reset => return Ok(()),
|
||||
Updated => {
|
||||
self.finish2()?;
|
||||
self.finish()?;
|
||||
}
|
||||
Finalized => (),
|
||||
}
|
||||
@ -147,15 +235,8 @@ impl Hasher {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[deprecated(note = "use finish2 instead", since = "0.9.11")]
|
||||
pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
|
||||
self.finish2().map(|b| b.to_vec())
|
||||
}
|
||||
|
||||
/// Returns the hash of the data written and resets the hasher.
|
||||
///
|
||||
/// Unlike `finish`, this method does not allocate.
|
||||
pub fn finish2(&mut self) -> Result<DigestBytes, ErrorStack> {
|
||||
/// Returns the hash of the data written and resets the non-XOF hasher.
|
||||
pub fn finish(&mut self) -> Result<DigestBytes, ErrorStack> {
|
||||
if self.state == Finalized {
|
||||
self.init()?;
|
||||
}
|
||||
@ -174,6 +255,24 @@ impl Hasher {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the hash of the data into the supplied buf and resets the XOF hasher.
|
||||
/// The hash will be as long as the buf.
|
||||
#[cfg(ossl111)]
|
||||
pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> {
|
||||
if self.state == Finalized {
|
||||
self.init()?;
|
||||
}
|
||||
unsafe {
|
||||
cvt(ffi::EVP_DigestFinalXOF(
|
||||
self.ctx,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len(),
|
||||
))?;
|
||||
self.state = Finalized;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Hasher {
|
||||
@ -210,7 +309,7 @@ impl Drop for Hasher {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if self.state != Finalized {
|
||||
drop(self.finish2());
|
||||
drop(self.finish());
|
||||
}
|
||||
EVP_MD_CTX_free(self.ctx);
|
||||
}
|
||||
@ -223,8 +322,8 @@ impl Drop for Hasher {
|
||||
/// store the digest data.
|
||||
#[derive(Copy)]
|
||||
pub struct DigestBytes {
|
||||
buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
|
||||
len: usize,
|
||||
pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
|
||||
pub(crate) len: usize,
|
||||
}
|
||||
|
||||
impl Clone for DigestBytes {
|
||||
@ -263,59 +362,72 @@ impl fmt::Debug for DigestBytes {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(note = "use hash2 instead", since = "0.9.11")]
|
||||
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
|
||||
hash2(t, data).map(|b| b.to_vec())
|
||||
}
|
||||
|
||||
/// Computes the hash of the `data` with the hash `t`.
|
||||
///
|
||||
/// Unlike `hash`, this function does not allocate the return value.
|
||||
pub fn hash2(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
|
||||
/// Computes the hash of the `data` with the non-XOF hasher `t`.
|
||||
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
|
||||
let mut h = Hasher::new(t)?;
|
||||
h.update(data)?;
|
||||
h.finish2()
|
||||
h.finish()
|
||||
}
|
||||
|
||||
/// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`.
|
||||
#[cfg(ossl111)]
|
||||
pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> {
|
||||
let mut h = Hasher::new(t)?;
|
||||
h.update(data)?;
|
||||
h.finish_xof(buf)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex::{FromHex, ToHex};
|
||||
use hex::{self, FromHex};
|
||||
use std::io::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
|
||||
let res = hash2(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
|
||||
assert_eq!(res.to_hex(), hashtest.1);
|
||||
let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
|
||||
assert_eq!(hex::encode(res), hashtest.1);
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
|
||||
let expected = Vec::from_hex(hashtest.1).unwrap();
|
||||
let mut buf = vec![0; expected.len()];
|
||||
hash_xof(
|
||||
hashtype,
|
||||
&Vec::from_hex(hashtest.0).unwrap(),
|
||||
buf.as_mut_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(buf, expected);
|
||||
}
|
||||
|
||||
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
|
||||
let _ = h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap();
|
||||
let res = h.finish2().unwrap();
|
||||
assert_eq!(res.to_hex(), hashtest.1);
|
||||
let res = h.finish().unwrap();
|
||||
assert_eq!(hex::encode(res), hashtest.1);
|
||||
}
|
||||
|
||||
// Test vectors from http://www.nsrl.nist.gov/testdata/
|
||||
#[allow(non_upper_case_globals)]
|
||||
const md5_tests: [(&'static str, &'static str); 13] =
|
||||
[
|
||||
("", "d41d8cd98f00b204e9800998ecf8427e"),
|
||||
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
|
||||
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
|
||||
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
|
||||
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
|
||||
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
|
||||
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
|
||||
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
|
||||
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
|
||||
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
|
||||
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
|
||||
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
|
||||
(
|
||||
"AAED18DBE8938C19ED734A8D",
|
||||
"6f80fb775f27e0a4ce5c2f42fc72c5f1",
|
||||
),
|
||||
];
|
||||
const md5_tests: [(&'static str, &'static str); 13] = [
|
||||
("", "d41d8cd98f00b204e9800998ecf8427e"),
|
||||
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
|
||||
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
|
||||
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
|
||||
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
|
||||
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
|
||||
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
|
||||
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
|
||||
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
|
||||
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
|
||||
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
|
||||
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
|
||||
(
|
||||
"AAED18DBE8938C19ED734A8D",
|
||||
"6f80fb775f27e0a4ce5c2f42fc72c5f1",
|
||||
),
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_md5() {
|
||||
@ -337,9 +449,9 @@ mod tests {
|
||||
let mut h = Hasher::new(MessageDigest::md5()).unwrap();
|
||||
h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap())
|
||||
.unwrap();
|
||||
h.finish2().unwrap();
|
||||
let res = h.finish2().unwrap();
|
||||
let null = hash2(MessageDigest::md5(), &[]).unwrap();
|
||||
h.finish().unwrap();
|
||||
let res = h.finish().unwrap();
|
||||
let null = hash(MessageDigest::md5(), &[]).unwrap();
|
||||
assert_eq!(&*res, &*null);
|
||||
}
|
||||
|
||||
@ -358,19 +470,19 @@ mod tests {
|
||||
println!("Clone an updated hasher");
|
||||
let mut h2 = h1.clone();
|
||||
h2.write_all(&inp[p..]).unwrap();
|
||||
let res = h2.finish2().unwrap();
|
||||
assert_eq!(res.to_hex(), md5_tests[i].1);
|
||||
let res = h2.finish().unwrap();
|
||||
assert_eq!(hex::encode(res), md5_tests[i].1);
|
||||
}
|
||||
h1.write_all(&inp[p..]).unwrap();
|
||||
let res = h1.finish2().unwrap();
|
||||
assert_eq!(res.to_hex(), md5_tests[i].1);
|
||||
let res = h1.finish().unwrap();
|
||||
assert_eq!(hex::encode(res), md5_tests[i].1);
|
||||
|
||||
println!("Clone a finished hasher");
|
||||
let mut h3 = h1.clone();
|
||||
h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap())
|
||||
.unwrap();
|
||||
let res = h3.finish2().unwrap();
|
||||
assert_eq!(res.to_hex(), md5_tests[i + 1].1);
|
||||
let res = h3.finish().unwrap();
|
||||
assert_eq!(hex::encode(res), md5_tests[i + 1].1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -384,18 +496,94 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_sha256() {
|
||||
let tests = [
|
||||
(
|
||||
"616263",
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
||||
),
|
||||
];
|
||||
let tests = [(
|
||||
"616263",
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha256(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_sha3_224() {
|
||||
let tests = [(
|
||||
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913",
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha3_224(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_sha3_256() {
|
||||
let tests = [(
|
||||
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61",
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha3_256(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_sha3_384() {
|
||||
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"966ee786ab3482dd811bf7c8fa8db79aa1f52f6c3c369942ef14240ebd857c6ff626ec35d9e131ff64d328\
|
||||
ef2008ff16"
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha3_384(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_sha3_512() {
|
||||
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"c072288ef728cd53a029c47687960b9225893532f42b923156e37020bdc1eda753aafbf30af859d4f4c3a1\
|
||||
807caee3a79f8eb02dcd61589fbbdf5f40c8787a72"
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha3_512(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_shake_128() {
|
||||
let tests = [(
|
||||
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"49d0697ff508111d8b84f15e46daf135",
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_xof_test(MessageDigest::shake_128(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
#[test]
|
||||
fn test_shake_256() {
|
||||
let tests = [(
|
||||
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
|
||||
"4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697",
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_xof_test(MessageDigest::shake_256(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ripemd160() {
|
||||
let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")];
|
||||
@ -404,4 +592,12 @@ mod tests {
|
||||
hash_test(MessageDigest::ripemd160(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_nid() {
|
||||
assert_eq!(
|
||||
MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(),
|
||||
MessageDigest::sha256().as_ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,129 @@
|
||||
#![doc(html_root_url="https://docs.rs/openssl/0.9")]
|
||||
//! Bindings to OpenSSL
|
||||
//!
|
||||
//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
|
||||
//! 1.1.1 and LibreSSL versions 2.5 through 2.8 are supported.
|
||||
//!
|
||||
//! # Building
|
||||
//!
|
||||
//! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate
|
||||
//! OpenSSL.
|
||||
//!
|
||||
//! ## Vendored
|
||||
//!
|
||||
//! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to
|
||||
//! a copy of OpenSSL. The build process requires a C compiler, perl, and make. The OpenSSL version will generally track
|
||||
//! the newest OpenSSL release, and changes to the version are *not* considered breaking changes.
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! openssl = { version = "0.10", features = ["vendored"] }
|
||||
//! ```
|
||||
//!
|
||||
//! The vendored copy will not be configured to automatically find the system's root certificates, but the
|
||||
//! `openssl-probe` crate can be used to do that instead.
|
||||
//!
|
||||
//! ## Automatic
|
||||
//!
|
||||
//! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows.
|
||||
//! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation.
|
||||
//!
|
||||
//! ```not_rust
|
||||
//! # macOS
|
||||
//! $ brew install openssl@1.1
|
||||
//!
|
||||
//! # Arch Linux
|
||||
//! $ sudo pacman -S pkg-config openssl
|
||||
//!
|
||||
//! # Debian and Ubuntu
|
||||
//! $ sudo apt-get install pkg-config libssl-dev
|
||||
//!
|
||||
//! # Fedora
|
||||
//! $ sudo dnf install pkg-config openssl-devel
|
||||
//! ```
|
||||
//!
|
||||
//! ## Manual
|
||||
//!
|
||||
//! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will
|
||||
//! override the automatic detection logic.
|
||||
//!
|
||||
//! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and
|
||||
//! `include` subdirectories containing the libraries and headers respectively.
|
||||
//! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and
|
||||
//! headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout.
|
||||
//! * `OPENSSL_STATIC` - If set, the crate will statically link to OpenSSL rather than dynamically link.
|
||||
//! * `OPENSSL_LIBS` - If set, a `:`-separated list of library names to link to (e.g. `ssl:crypto`). This can be used
|
||||
//! if nonstandard library names were used for whatever reason.
|
||||
//!
|
||||
//! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g.
|
||||
//! `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling.
|
||||
//!
|
||||
//! # Feature Detection
|
||||
//!
|
||||
//! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the
|
||||
//! functionality available in the version being linked against. This means that methods, constants, and even modules
|
||||
//! will be present when building against one version of OpenSSL but not when building against another! APIs will
|
||||
//! document any version-specific availability restrictions.
|
||||
//!
|
||||
//! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys`
|
||||
//! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER`
|
||||
//! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version:
|
||||
//! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`.
|
||||
//!
|
||||
//! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile
|
||||
//! against OpenSSL versions that don't support TLSv1.3:
|
||||
//!
|
||||
//! Cargo.toml:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! openssl-sys = "0.9"
|
||||
//! openssl = "0.10"
|
||||
//! ```
|
||||
//!
|
||||
//! build.rs:
|
||||
//!
|
||||
//! ```
|
||||
//! use std::env;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
|
||||
//! let version = u64::from_str_radix(&v, 16).unwrap();
|
||||
//!
|
||||
//! if version >= 0x1_01_01_00_0 {
|
||||
//! println!("cargo:rustc-cfg=openssl111");
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! lib.rs:
|
||||
//!
|
||||
//! ```
|
||||
//! use openssl::ssl::{SslConnector, SslMethod};
|
||||
//!
|
||||
//! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||
//!
|
||||
//! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version
|
||||
//! #[cfg(openssl111)]
|
||||
//! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap();
|
||||
//! ```
|
||||
#![doc(html_root_url = "https://docs.rs/openssl/0.10")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
#[macro_use]
|
||||
extern crate foreign_types;
|
||||
extern crate libc;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
extern crate openssl_sys as ffi;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate hex;
|
||||
#[cfg(test)]
|
||||
extern crate tempdir;
|
||||
#[cfg(test)]
|
||||
extern crate data_encoding;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use ffi::init;
|
||||
@ -35,33 +144,35 @@ pub mod bn;
|
||||
#[cfg(not(libressl))]
|
||||
pub mod cms;
|
||||
pub mod conf;
|
||||
pub mod crypto;
|
||||
pub mod derive;
|
||||
pub mod dh;
|
||||
pub mod dsa;
|
||||
pub mod ec;
|
||||
pub mod ec_key;
|
||||
pub mod ecdsa;
|
||||
pub mod envelope;
|
||||
pub mod error;
|
||||
pub mod ex_data;
|
||||
#[cfg(not(libressl))]
|
||||
pub mod fips;
|
||||
pub mod hash;
|
||||
pub mod memcmp;
|
||||
pub mod nid;
|
||||
pub mod ocsp;
|
||||
pub mod pkcs12;
|
||||
pub mod pkcs5;
|
||||
pub mod pkcs7;
|
||||
pub mod pkey;
|
||||
pub mod rand;
|
||||
pub mod rsa;
|
||||
pub mod sign;
|
||||
pub mod sha;
|
||||
pub mod sign;
|
||||
pub mod srtp;
|
||||
pub mod ssl;
|
||||
pub mod stack;
|
||||
pub mod string;
|
||||
pub mod symm;
|
||||
pub mod types;
|
||||
pub mod version;
|
||||
pub mod x509;
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
mod verify;
|
||||
|
||||
fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
|
||||
if r.is_null() {
|
||||
@ -80,5 +191,9 @@ fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
|
||||
}
|
||||
|
||||
fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
|
||||
if r < 0 { Err(ErrorStack::get()) } else { Ok(r) }
|
||||
if r < 0 {
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,9 @@
|
||||
|
||||
macro_rules! private_key_from_pem {
|
||||
($t:ident, $f:path) => {
|
||||
from_pem_inner!(/// Deserializes a PEM-formatted private key.
|
||||
private_key_from_pem, $t, $f);
|
||||
($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $(#[$m3:meta])* $n3:ident, $t:ty, $f:path) => {
|
||||
from_pem!($(#[$m])* $n, $t, $f);
|
||||
|
||||
/// Deserializes a PEM-formatted private key, using the supplied password if the key is
|
||||
/// encrypted.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `passphrase` contains an embedded null.
|
||||
pub fn private_key_from_pem_passphrase(pem: &[u8],
|
||||
passphrase: &[u8])
|
||||
-> Result<$t, ::error::ErrorStack> {
|
||||
$(#[$m2])*
|
||||
pub fn $n2(pem: &[u8], passphrase: &[u8]) -> Result<$t, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let bio = try!(::bio::MemBioSlice::new(pem));
|
||||
@ -21,18 +12,12 @@ macro_rules! private_key_from_pem {
|
||||
ptr::null_mut(),
|
||||
None,
|
||||
passphrase.as_ptr() as *const _ as *mut _))
|
||||
.map($t)
|
||||
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes a PEM-formatted private key, using a callback to retrieve a password if the
|
||||
/// key is encrypted.
|
||||
///
|
||||
/// The callback should copy the password into the provided buffer and return the number of
|
||||
/// bytes written.
|
||||
pub fn private_key_from_pem_callback<F>(pem: &[u8],
|
||||
callback: F)
|
||||
-> Result<$t, ::error::ErrorStack>
|
||||
$(#[$m3])*
|
||||
pub fn $n3<F>(pem: &[u8], callback: F) -> Result<$t, ::error::ErrorStack>
|
||||
where F: FnOnce(&mut [u8]) -> Result<usize, ::error::ErrorStack>
|
||||
{
|
||||
unsafe {
|
||||
@ -43,16 +28,16 @@ macro_rules! private_key_from_pem {
|
||||
ptr::null_mut(),
|
||||
Some(::util::invoke_passwd_cb::<F>),
|
||||
&mut cb as *mut _ as *mut _))
|
||||
.map($t)
|
||||
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! private_key_to_pem {
|
||||
($f:path) => {
|
||||
/// Serializes the private key to PEM.
|
||||
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $f:path) => {
|
||||
$(#[$m])*
|
||||
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let bio = try!(::bio::MemBio::new());
|
||||
try!(cvt($f(bio.as_ptr(),
|
||||
@ -66,12 +51,12 @@ macro_rules! private_key_to_pem {
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes the private key to PEM, encrypting it with the specified symmetric cipher and
|
||||
/// passphrase.
|
||||
pub fn private_key_to_pem_passphrase(&self,
|
||||
cipher: ::symm::Cipher,
|
||||
passphrase: &[u8])
|
||||
-> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
$(#[$m2])*
|
||||
pub fn $n2(
|
||||
&self,
|
||||
cipher: ::symm::Cipher,
|
||||
passphrase: &[u8]
|
||||
) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let bio = try!(::bio::MemBio::new());
|
||||
assert!(passphrase.len() <= ::libc::c_int::max_value() as usize);
|
||||
@ -88,9 +73,9 @@ macro_rules! private_key_to_pem {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! to_pem_inner {
|
||||
(#[$m:meta] $n:ident, $f:path) => {
|
||||
#[$m]
|
||||
macro_rules! to_pem {
|
||||
($(#[$m:meta])* $n:ident, $f:path) => {
|
||||
$(#[$m])*
|
||||
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let bio = try!(::bio::MemBio::new());
|
||||
@ -101,23 +86,9 @@ macro_rules! to_pem_inner {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! public_key_to_pem {
|
||||
($f:path) => {
|
||||
to_pem_inner!(/// Serializes a public key to PEM.
|
||||
public_key_to_pem, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! to_pem {
|
||||
($f:path) => {
|
||||
to_pem_inner!(/// Serializes this value to PEM.
|
||||
to_pem, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! to_der_inner {
|
||||
(#[$m:meta] $n:ident, $f:path) => {
|
||||
#[$m]
|
||||
macro_rules! to_der {
|
||||
($(#[$m:meta])* $n:ident, $f:path) => {
|
||||
$(#[$m])*
|
||||
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let len = try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
|
||||
@ -131,91 +102,34 @@ macro_rules! to_der_inner {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! to_der {
|
||||
($f:path) => {
|
||||
to_der_inner!(/// Serializes this value to DER.
|
||||
to_der, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! private_key_to_der {
|
||||
($f:path) => {
|
||||
to_der_inner!(/// Serializes the private key to DER.
|
||||
private_key_to_der, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! public_key_to_der {
|
||||
($f:path) => {
|
||||
to_der_inner!(/// Serializes the public key to DER.
|
||||
public_key_to_der, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_der_inner {
|
||||
(#[$m:meta] $n:ident, $t:ident, $f:path) => {
|
||||
#[$m]
|
||||
macro_rules! from_der {
|
||||
($(#[$m:meta])* $n:ident, $t:ty, $f:path) => {
|
||||
$(#[$m])*
|
||||
pub fn $n(der: &[u8]) -> Result<$t, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
::ffi::init();
|
||||
let len = ::std::cmp::min(der.len(), ::libc::c_long::max_value() as usize) as ::libc::c_long;
|
||||
::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len))
|
||||
.map($t)
|
||||
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_der {
|
||||
($t:ident, $f:path) => {
|
||||
from_der_inner!(/// Deserializes a value from DER-formatted data.
|
||||
from_der, $t, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! private_key_from_der {
|
||||
($t:ident, $f:path) => {
|
||||
from_der_inner!(/// Deserializes a private key from DER-formatted data.
|
||||
private_key_from_der, $t, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! public_key_from_der {
|
||||
($t:ident, $f:path) => {
|
||||
from_der_inner!(/// Deserializes a public key from DER-formatted data.
|
||||
public_key_from_der, $t, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_pem_inner {
|
||||
(#[$m:meta] $n:ident, $t:ident, $f:path) => {
|
||||
#[$m]
|
||||
macro_rules! from_pem {
|
||||
($(#[$m:meta])* $n:ident, $t:ty, $f:path) => {
|
||||
$(#[$m])*
|
||||
pub fn $n(pem: &[u8]) -> Result<$t, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
::init();
|
||||
let bio = try!(::bio::MemBioSlice::new(pem));
|
||||
cvt_p($f(bio.as_ptr(), ::std::ptr::null_mut(), None, ::std::ptr::null_mut()))
|
||||
.map($t)
|
||||
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! public_key_from_pem {
|
||||
($t:ident, $f:path) => {
|
||||
from_pem_inner!(/// Deserializes a public key from PEM-formatted data.
|
||||
public_key_from_pem, $t, $f);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_pem {
|
||||
($t:ident, $f:path) => {
|
||||
from_pem_inner!(/// Deserializes a value from PEM-formatted data.
|
||||
from_pem, $t, $f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
macro_rules! foreign_type_and_impl_send_sync {
|
||||
(
|
||||
$(#[$impl_attr:meta])*
|
||||
@ -246,3 +160,110 @@ macro_rules! foreign_type_and_impl_send_sync {
|
||||
unsafe impl Sync for $borrowed{}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! generic_foreign_type_and_impl_send_sync {
|
||||
(
|
||||
$(#[$impl_attr:meta])*
|
||||
type CType = $ctype:ty;
|
||||
fn drop = $drop:expr;
|
||||
$(fn clone = $clone:expr;)*
|
||||
|
||||
$(#[$owned_attr:meta])*
|
||||
pub struct $owned:ident<T>;
|
||||
$(#[$borrowed_attr:meta])*
|
||||
pub struct $borrowed:ident<T>;
|
||||
) => {
|
||||
$(#[$owned_attr])*
|
||||
pub struct $owned<T>(*mut $ctype, ::std::marker::PhantomData<T>);
|
||||
|
||||
$(#[$impl_attr])*
|
||||
impl<T> ::foreign_types::ForeignType for $owned<T> {
|
||||
type CType = $ctype;
|
||||
type Ref = $borrowed<T>;
|
||||
|
||||
#[inline]
|
||||
unsafe fn from_ptr(ptr: *mut $ctype) -> $owned<T> {
|
||||
$owned(ptr, ::std::marker::PhantomData)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut $ctype {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for $owned<T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe { $drop(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl<T> Clone for $owned<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> $owned<T> {
|
||||
unsafe {
|
||||
let handle: *mut $ctype = $clone(self.0);
|
||||
::foreign_types::ForeignType::from_ptr(handle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ::std::borrow::ToOwned for $borrowed<T> {
|
||||
type Owned = $owned<T>;
|
||||
#[inline]
|
||||
fn to_owned(&self) -> $owned<T> {
|
||||
unsafe {
|
||||
let handle: *mut $ctype =
|
||||
$clone(::foreign_types::ForeignTypeRef::as_ptr(self));
|
||||
$crate::ForeignType::from_ptr(handle)
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
impl<T> ::std::ops::Deref for $owned<T> {
|
||||
type Target = $borrowed<T>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &$borrowed<T> {
|
||||
unsafe { ::foreign_types::ForeignTypeRef::from_ptr(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ::std::ops::DerefMut for $owned<T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut $borrowed<T> {
|
||||
unsafe { ::foreign_types::ForeignTypeRef::from_ptr_mut(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ::std::borrow::Borrow<$borrowed<T>> for $owned<T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &$borrowed<T> {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ::std::convert::AsRef<$borrowed<T>> for $owned<T> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &$borrowed<T> {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
$(#[$borrowed_attr])*
|
||||
pub struct $borrowed<T>(::foreign_types::Opaque, ::std::marker::PhantomData<T>);
|
||||
|
||||
$(#[$impl_attr])*
|
||||
impl<T> ::foreign_types::ForeignTypeRef for $borrowed<T> {
|
||||
type CType = $ctype;
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for $owned<T>{}
|
||||
unsafe impl<T> Send for $borrowed<T>{}
|
||||
unsafe impl<T> Sync for $owned<T>{}
|
||||
unsafe impl<T> Sync for $borrowed<T>{}
|
||||
};
|
||||
}
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
//! assert!(!eq(&a, &b));
|
||||
//! assert!(!eq(&a, &c));
|
||||
//! ```
|
||||
use libc::size_t;
|
||||
use ffi;
|
||||
use libc::size_t;
|
||||
|
||||
/// Returns `true` iff `a` and `b` contain the same bytes.
|
||||
///
|
||||
|
||||
2018
openssl/src/nid.rs
2018
openssl/src/nid.rs
File diff suppressed because it is too large
Load Diff
@ -1,69 +1,33 @@
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::{c_int, c_long, c_ulong};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use asn1::Asn1GeneralizedTimeRef;
|
||||
use error::ErrorStack;
|
||||
use hash::MessageDigest;
|
||||
use stack::StackRef;
|
||||
use x509::store::X509StoreRef;
|
||||
use x509::{X509, X509Ref};
|
||||
use x509::{X509Ref, X509};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
bitflags! {
|
||||
pub struct Flag: c_ulong {
|
||||
const FLAG_NO_CERTS = ffi::OCSP_NOCERTS;
|
||||
const FLAG_NO_INTERN = ffi::OCSP_NOINTERN;
|
||||
const FLAG_NO_CHAIN = ffi::OCSP_NOCHAIN;
|
||||
const FLAG_NO_VERIFY = ffi::OCSP_NOVERIFY;
|
||||
const FLAG_NO_EXPLICIT = ffi::OCSP_NOEXPLICIT;
|
||||
const FLAG_NO_CA_SIGN = ffi::OCSP_NOCASIGN;
|
||||
const FLAG_NO_DELEGATED = ffi::OCSP_NODELEGATED;
|
||||
const FLAG_NO_CHECKS = ffi::OCSP_NOCHECKS;
|
||||
const FLAG_TRUST_OTHER = ffi::OCSP_TRUSTOTHER;
|
||||
const FLAG_RESPID_KEY = ffi::OCSP_RESPID_KEY;
|
||||
const FLAG_NO_TIME = ffi::OCSP_NOTIME;
|
||||
pub struct OcspFlag: c_ulong {
|
||||
const NO_CERTS = ffi::OCSP_NOCERTS;
|
||||
const NO_INTERN = ffi::OCSP_NOINTERN;
|
||||
const NO_CHAIN = ffi::OCSP_NOCHAIN;
|
||||
const NO_VERIFY = ffi::OCSP_NOVERIFY;
|
||||
const NO_EXPLICIT = ffi::OCSP_NOEXPLICIT;
|
||||
const NO_CA_SIGN = ffi::OCSP_NOCASIGN;
|
||||
const NO_DELEGATED = ffi::OCSP_NODELEGATED;
|
||||
const NO_CHECKS = ffi::OCSP_NOCHECKS;
|
||||
const TRUST_OTHER = ffi::OCSP_TRUSTOTHER;
|
||||
const RESPID_KEY = ffi::OCSP_RESPID_KEY;
|
||||
const NO_TIME = ffi::OCSP_NOTIME;
|
||||
}
|
||||
}
|
||||
|
||||
pub const RESPONSE_STATUS_SUCCESSFUL: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL);
|
||||
pub const RESPONSE_STATUS_MALFORMED_REQUEST: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST);
|
||||
pub const RESPONSE_STATUS_INTERNAL_ERROR: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR);
|
||||
pub const RESPONSE_STATUS_TRY_LATER: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER);
|
||||
pub const RESPONSE_STATUS_SIG_REQUIRED: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED);
|
||||
pub const RESPONSE_STATUS_UNAUTHORIZED: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED);
|
||||
|
||||
pub const CERT_STATUS_GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD);
|
||||
pub const CERT_STATUS_REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED);
|
||||
pub const CERT_STATUS_UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN);
|
||||
|
||||
pub const REVOKED_STATUS_NO_STATUS: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS);
|
||||
pub const REVOKED_STATUS_UNSPECIFIED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED);
|
||||
pub const REVOKED_STATUS_KEY_COMPROMISE: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE);
|
||||
pub const REVOKED_STATUS_CA_COMPROMISE: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE);
|
||||
pub const REVOKED_STATUS_AFFILIATION_CHANGED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED);
|
||||
pub const REVOKED_STATUS_SUPERSEDED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED);
|
||||
pub const REVOKED_STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION);
|
||||
pub const REVOKED_STATUS_CERTIFICATE_HOLD: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD);
|
||||
pub const REVOKED_STATUS_REMOVE_FROM_CRL: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct OcspResponseStatus(c_int);
|
||||
|
||||
@ -75,6 +39,19 @@ impl OcspResponseStatus {
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub const SUCCESSFUL: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL);
|
||||
pub const MALFORMED_REQUEST: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST);
|
||||
pub const INTERNAL_ERROR: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR);
|
||||
pub const TRY_LATER: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER);
|
||||
pub const SIG_REQUIRED: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED);
|
||||
pub const UNAUTHORIZED: OcspResponseStatus =
|
||||
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
@ -88,6 +65,10 @@ impl OcspCertStatus {
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub const GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD);
|
||||
pub const REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED);
|
||||
pub const UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
@ -101,9 +82,27 @@ impl OcspRevokedStatus {
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub const NO_STATUS: OcspRevokedStatus = OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS);
|
||||
pub const UNSPECIFIED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED);
|
||||
pub const KEY_COMPROMISE: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE);
|
||||
pub const CA_COMPROMISE: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE);
|
||||
pub const AFFILIATION_CHANGED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED);
|
||||
pub const STATUS_SUPERSEDED: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED);
|
||||
pub const STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION);
|
||||
pub const STATUS_CERTIFICATE_HOLD: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD);
|
||||
pub const REMOVE_FROM_CRL: OcspRevokedStatus =
|
||||
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL);
|
||||
}
|
||||
|
||||
pub struct Status<'a> {
|
||||
pub struct OcspStatus<'a> {
|
||||
/// The overall status of the response.
|
||||
pub status: OcspCertStatus,
|
||||
/// If `status` is `CERT_STATUS_REVOKED`, the reason for the revocation.
|
||||
@ -116,7 +115,7 @@ pub struct Status<'a> {
|
||||
pub next_update: &'a Asn1GeneralizedTimeRef,
|
||||
}
|
||||
|
||||
impl<'a> Status<'a> {
|
||||
impl<'a> OcspStatus<'a> {
|
||||
/// Checks validity of the `this_update` and `next_update` fields.
|
||||
///
|
||||
/// The `nsec` parameter specifies an amount of slack time that will be used when comparing
|
||||
@ -131,7 +130,8 @@ impl<'a> Status<'a> {
|
||||
self.next_update.as_ptr(),
|
||||
nsec as c_long,
|
||||
maxsec.map(|n| n as c_long).unwrap_or(-1),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,7 +153,7 @@ impl OcspBasicResponseRef {
|
||||
&self,
|
||||
certs: &StackRef<X509>,
|
||||
store: &X509StoreRef,
|
||||
flags: Flag,
|
||||
flags: OcspFlag,
|
||||
) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::OCSP_basic_verify(
|
||||
@ -161,12 +161,13 @@ impl OcspBasicResponseRef {
|
||||
certs.as_ptr(),
|
||||
store.as_ptr(),
|
||||
flags.bits(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Looks up the status for the specified certificate ID.
|
||||
pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option<Status<'a>> {
|
||||
pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option<OcspStatus<'a>> {
|
||||
unsafe {
|
||||
let mut status = ffi::V_OCSP_CERTSTATUS_UNKNOWN;
|
||||
let mut reason = ffi::OCSP_REVOKED_STATUS_NOSTATUS;
|
||||
@ -189,7 +190,7 @@ impl OcspBasicResponseRef {
|
||||
} else {
|
||||
Some(Asn1GeneralizedTimeRef::from_ptr(revocation_time))
|
||||
};
|
||||
Some(Status {
|
||||
Some(OcspStatus {
|
||||
status: OcspCertStatus(status),
|
||||
reason: OcspRevokedStatus(status),
|
||||
revocation_time: revocation_time,
|
||||
@ -223,7 +224,8 @@ impl OcspCertId {
|
||||
digest.as_ptr(),
|
||||
subject.as_ptr(),
|
||||
issuer.as_ptr(),
|
||||
)).map(OcspCertId)
|
||||
))
|
||||
.map(OcspCertId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,15 +252,33 @@ impl OcspResponse {
|
||||
cvt_p(ffi::OCSP_response_create(
|
||||
status.as_raw(),
|
||||
body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()),
|
||||
)).map(OcspResponse)
|
||||
))
|
||||
.map(OcspResponse)
|
||||
}
|
||||
}
|
||||
|
||||
from_der!(OcspResponse, ffi::d2i_OCSP_RESPONSE);
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded OCSP response.
|
||||
///
|
||||
/// This corresponds to [`d2i_OCSP_RESPONSE`].
|
||||
///
|
||||
/// [`d2i_OCSP_RESPONSE`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_OCSP_RESPONSE.html
|
||||
from_der,
|
||||
OcspResponse,
|
||||
ffi::d2i_OCSP_RESPONSE
|
||||
}
|
||||
}
|
||||
|
||||
impl OcspResponseRef {
|
||||
to_der!(ffi::i2d_OCSP_RESPONSE);
|
||||
to_der! {
|
||||
/// Serializes the response to its standard DER encoding.
|
||||
///
|
||||
/// This corresponds to [`i2d_OCSP_RESPONSE`].
|
||||
///
|
||||
/// [`i2d_OCSP_RESPONSE`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_OCSP_RESPONSE.html
|
||||
to_der,
|
||||
ffi::i2d_OCSP_RESPONSE
|
||||
}
|
||||
|
||||
/// Returns the status of the response.
|
||||
pub fn status(&self) -> OcspResponseStatus {
|
||||
@ -290,11 +310,28 @@ impl OcspRequest {
|
||||
}
|
||||
}
|
||||
|
||||
from_der!(OcspRequest, ffi::d2i_OCSP_REQUEST);
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded OCSP request.
|
||||
///
|
||||
/// This corresponds to [`d2i_OCSP_REQUEST`].
|
||||
///
|
||||
/// [`d2i_OCSP_REQUEST`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_OCSP_REQUEST.html
|
||||
from_der,
|
||||
OcspRequest,
|
||||
ffi::d2i_OCSP_REQUEST
|
||||
}
|
||||
}
|
||||
|
||||
impl OcspRequestRef {
|
||||
to_der!(ffi::i2d_OCSP_REQUEST);
|
||||
to_der! {
|
||||
/// Serializes the request to its standard DER encoding.
|
||||
///
|
||||
/// This corresponds to [`i2d_OCSP_REQUEST`].
|
||||
///
|
||||
/// [`i2d_OCSP_REQUEST`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_OCSP_REQUEST.html
|
||||
to_der,
|
||||
ffi::i2d_OCSP_REQUEST
|
||||
}
|
||||
|
||||
pub fn add_id(&mut self, id: OcspCertId) -> Result<&mut OcspOneReqRef, ErrorStack> {
|
||||
unsafe {
|
||||
|
||||
@ -3,15 +3,15 @@
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use pkey::{PKey, PKeyRef};
|
||||
use error::ErrorStack;
|
||||
use x509::X509;
|
||||
use nid::Nid;
|
||||
use pkey::{HasPrivate, PKey, PKeyRef, Private};
|
||||
use stack::Stack;
|
||||
use nid;
|
||||
use x509::{X509Ref, X509};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::PKCS12;
|
||||
@ -22,13 +22,20 @@ foreign_type_and_impl_send_sync! {
|
||||
}
|
||||
|
||||
impl Pkcs12Ref {
|
||||
to_der!(ffi::i2d_PKCS12);
|
||||
to_der! {
|
||||
/// Serializes the `Pkcs12` to its standard DER encoding.
|
||||
///
|
||||
/// This corresponds to [`i2d_PKCS12`].
|
||||
///
|
||||
/// [`i2d_PKCS12`]: https://www.openssl.org/docs/manmaster/man3/i2d_PKCS12.html
|
||||
to_der,
|
||||
ffi::i2d_PKCS12
|
||||
}
|
||||
|
||||
/// Extracts the contents of the `Pkcs12`.
|
||||
// FIXME should take an &[u8]
|
||||
pub fn parse(&self, pass: &str) -> Result<ParsedPkcs12, ErrorStack> {
|
||||
unsafe {
|
||||
let pass = CString::new(pass).unwrap();
|
||||
let pass = CString::new(pass.as_bytes()).unwrap();
|
||||
|
||||
let mut pkey = ptr::null_mut();
|
||||
let mut cert = ptr::null_mut();
|
||||
@ -46,9 +53,9 @@ impl Pkcs12Ref {
|
||||
let cert = X509::from_ptr(cert);
|
||||
|
||||
let chain = if chain.is_null() {
|
||||
Stack::new()?
|
||||
None
|
||||
} else {
|
||||
Stack::from_ptr(chain)
|
||||
Some(Stack::from_ptr(chain))
|
||||
};
|
||||
|
||||
Ok(ParsedPkcs12 {
|
||||
@ -61,7 +68,16 @@ impl Pkcs12Ref {
|
||||
}
|
||||
|
||||
impl Pkcs12 {
|
||||
from_der!(Pkcs12, ffi::d2i_PKCS12);
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded PKCS#12 archive.
|
||||
///
|
||||
/// This corresponds to [`d2i_PKCS12`].
|
||||
///
|
||||
/// [`d2i_PKCS12`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_PKCS12.html
|
||||
from_der,
|
||||
Pkcs12,
|
||||
ffi::d2i_PKCS12
|
||||
}
|
||||
|
||||
/// Creates a new builder for a protected pkcs12 certificate.
|
||||
///
|
||||
@ -75,8 +91,8 @@ impl Pkcs12 {
|
||||
ffi::init();
|
||||
|
||||
Pkcs12Builder {
|
||||
nid_key: nid::UNDEF, //nid::PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC,
|
||||
nid_cert: nid::UNDEF, //nid::PBE_WITHSHA1AND40BITRC2_CBC,
|
||||
nid_key: Nid::UNDEF, //nid::PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC,
|
||||
nid_cert: Nid::UNDEF, //nid::PBE_WITHSHA1AND40BITRC2_CBC,
|
||||
iter: ffi::PKCS12_DEFAULT_ITER,
|
||||
mac_iter: ffi::PKCS12_DEFAULT_ITER,
|
||||
ca: None,
|
||||
@ -85,15 +101,14 @@ impl Pkcs12 {
|
||||
}
|
||||
|
||||
pub struct ParsedPkcs12 {
|
||||
pub pkey: PKey,
|
||||
pub pkey: PKey<Private>,
|
||||
pub cert: X509,
|
||||
// FIXME Make this Option<Stack> in the next breaking release
|
||||
pub chain: Stack<X509>,
|
||||
pub chain: Option<Stack<X509>>,
|
||||
}
|
||||
|
||||
pub struct Pkcs12Builder {
|
||||
nid_key: nid::Nid,
|
||||
nid_cert: nid::Nid,
|
||||
nid_key: Nid,
|
||||
nid_cert: Nid,
|
||||
iter: c_int,
|
||||
mac_iter: c_int,
|
||||
ca: Option<Stack<X509>>,
|
||||
@ -101,13 +116,13 @@ pub struct Pkcs12Builder {
|
||||
|
||||
impl Pkcs12Builder {
|
||||
/// The encryption algorithm that should be used for the key
|
||||
pub fn key_algorithm(&mut self, nid: nid::Nid) -> &mut Self {
|
||||
pub fn key_algorithm(&mut self, nid: Nid) -> &mut Self {
|
||||
self.nid_key = nid;
|
||||
self
|
||||
}
|
||||
|
||||
/// The encryption algorithm that should be used for the cert
|
||||
pub fn cert_algorithm(&mut self, nid: nid::Nid) -> &mut Self {
|
||||
pub fn cert_algorithm(&mut self, nid: Nid) -> &mut Self {
|
||||
self.nid_cert = nid;
|
||||
self
|
||||
}
|
||||
@ -142,21 +157,26 @@ impl Pkcs12Builder {
|
||||
/// * `friendly_name` - user defined name for the certificate
|
||||
/// * `pkey` - key to store
|
||||
/// * `cert` - certificate to store
|
||||
pub fn build(
|
||||
pub fn build<T>(
|
||||
self,
|
||||
password: &str,
|
||||
friendly_name: &str,
|
||||
pkey: &PKeyRef,
|
||||
cert: &X509,
|
||||
) -> Result<Pkcs12, ErrorStack> {
|
||||
pkey: &PKeyRef<T>,
|
||||
cert: &X509Ref,
|
||||
) -> Result<Pkcs12, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
let pass = CString::new(password).unwrap();
|
||||
let friendly_name = CString::new(friendly_name).unwrap();
|
||||
let pkey = pkey.as_ptr();
|
||||
let cert = cert.as_ptr();
|
||||
let ca = self.ca.as_ref().map(|ca| ca.as_ptr()).unwrap_or(
|
||||
ptr::null_mut(),
|
||||
);
|
||||
let ca = self
|
||||
.ca
|
||||
.as_ref()
|
||||
.map(|ca| ca.as_ptr())
|
||||
.unwrap_or(ptr::null_mut());
|
||||
let nid_key = self.nid_key.as_raw();
|
||||
let nid_cert = self.nid_cert.as_raw();
|
||||
|
||||
@ -176,7 +196,8 @@ impl Pkcs12Builder {
|
||||
self.iter,
|
||||
self.mac_iter,
|
||||
keytype,
|
||||
)).map(Pkcs12)
|
||||
))
|
||||
.map(Pkcs12)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -184,14 +205,14 @@ impl Pkcs12Builder {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hash::MessageDigest;
|
||||
use hex::ToHex;
|
||||
use hex;
|
||||
|
||||
use asn1::Asn1Time;
|
||||
use rsa::Rsa;
|
||||
use nid::Nid;
|
||||
use pkey::PKey;
|
||||
use nid;
|
||||
use x509::{X509, X509Name};
|
||||
use rsa::Rsa;
|
||||
use x509::extension::KeyUsage;
|
||||
use x509::{X509Name, X509};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -202,20 +223,14 @@ mod test {
|
||||
let parsed = pkcs12.parse("mypass").unwrap();
|
||||
|
||||
assert_eq!(
|
||||
parsed
|
||||
.cert
|
||||
.fingerprint(MessageDigest::sha1())
|
||||
.unwrap()
|
||||
.to_hex(),
|
||||
hex::encode(parsed.cert.digest(MessageDigest::sha1()).unwrap()),
|
||||
"59172d9313e84459bcff27f967e79e6e9217e584"
|
||||
);
|
||||
|
||||
assert_eq!(parsed.chain.len(), 1);
|
||||
let chain = parsed.chain.unwrap();
|
||||
assert_eq!(chain.len(), 1);
|
||||
assert_eq!(
|
||||
parsed.chain[0]
|
||||
.fingerprint(MessageDigest::sha1())
|
||||
.unwrap()
|
||||
.to_hex(),
|
||||
hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()),
|
||||
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
|
||||
);
|
||||
}
|
||||
@ -225,9 +240,7 @@ mod test {
|
||||
let der = include_bytes!("../test/keystore-empty-chain.p12");
|
||||
let pkcs12 = Pkcs12::from_der(der).unwrap();
|
||||
let parsed = pkcs12.parse("cassandra").unwrap();
|
||||
|
||||
assert_eq!(parsed.chain.len(), 0);
|
||||
assert_eq!(parsed.chain.into_iter().collect::<Vec<_>>().len(), 0);
|
||||
assert!(parsed.chain.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -237,7 +250,7 @@ mod test {
|
||||
let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
|
||||
let mut name = X509Name::builder().unwrap();
|
||||
name.append_entry_by_nid(nid::COMMONNAME, subject_name)
|
||||
name.append_entry_by_nid(Nid::COMMONNAME, subject_name)
|
||||
.unwrap();
|
||||
let name = name.build();
|
||||
|
||||
@ -268,8 +281,8 @@ mod test {
|
||||
let parsed = pkcs12.parse("mypass").unwrap();
|
||||
|
||||
assert_eq!(
|
||||
parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(),
|
||||
cert.fingerprint(MessageDigest::sha1()).unwrap()
|
||||
&*parsed.cert.digest(MessageDigest::sha1()).unwrap(),
|
||||
&*cert.digest(MessageDigest::sha1()).unwrap()
|
||||
);
|
||||
assert!(parsed.pkey.public_eq(&pkey));
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
use ffi;
|
||||
|
||||
use cvt;
|
||||
use error::ErrorStack;
|
||||
use hash::MessageDigest;
|
||||
use symm::Cipher;
|
||||
use error::ErrorStack;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||
pub struct KeyIvPair {
|
||||
@ -59,9 +59,10 @@ pub fn bytes_to_key(
|
||||
))?;
|
||||
|
||||
let mut key = vec![0; len as usize];
|
||||
let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(
|
||||
ptr::null_mut(),
|
||||
);
|
||||
let iv_ptr = iv
|
||||
.as_mut()
|
||||
.map(|v| v.as_mut_ptr())
|
||||
.unwrap_or(ptr::null_mut());
|
||||
|
||||
cvt(ffi::EVP_BytesToKey(
|
||||
cipher,
|
||||
@ -101,14 +102,15 @@ pub fn pbkdf2_hmac(
|
||||
hash.as_ptr(),
|
||||
key.len() as c_int,
|
||||
key.as_mut_ptr(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Derives a key from a password and salt using the scrypt algorithm.
|
||||
///
|
||||
/// Requires the `v110` feature and OpenSSL 1.1.0.
|
||||
#[cfg(all(feature = "v110", ossl110))]
|
||||
/// Requires OpenSSL 1.1.0 or newer.
|
||||
#[cfg(any(ossl110))]
|
||||
pub fn scrypt(
|
||||
pass: &[u8],
|
||||
salt: &[u8],
|
||||
@ -131,7 +133,8 @@ pub fn scrypt(
|
||||
maxmem,
|
||||
key.as_mut_ptr() as *mut _,
|
||||
key.len(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,24 +153,9 @@ mod tests {
|
||||
assert_eq!(
|
||||
buf,
|
||||
&[
|
||||
0x55_u8,
|
||||
0xac_u8,
|
||||
0x04_u8,
|
||||
0x6e_u8,
|
||||
0x56_u8,
|
||||
0xe3_u8,
|
||||
0x08_u8,
|
||||
0x9f_u8,
|
||||
0xec_u8,
|
||||
0x16_u8,
|
||||
0x91_u8,
|
||||
0xc2_u8,
|
||||
0x25_u8,
|
||||
0x44_u8,
|
||||
0xb6_u8,
|
||||
0x05_u8,
|
||||
]
|
||||
[..]
|
||||
0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, 0xec_u8,
|
||||
0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8,
|
||||
][..]
|
||||
);
|
||||
|
||||
super::pbkdf2_hmac(
|
||||
@ -176,28 +164,14 @@ mod tests {
|
||||
80000,
|
||||
MessageDigest::sha256(),
|
||||
&mut buf,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
buf,
|
||||
&[
|
||||
0x4d_u8,
|
||||
0xdc_u8,
|
||||
0xd8_u8,
|
||||
0xf6_u8,
|
||||
0x0b_u8,
|
||||
0x98_u8,
|
||||
0xbe_u8,
|
||||
0x21_u8,
|
||||
0x83_u8,
|
||||
0x0c_u8,
|
||||
0xee_u8,
|
||||
0x5e_u8,
|
||||
0xf2_u8,
|
||||
0x27_u8,
|
||||
0x01_u8,
|
||||
0xf9_u8,
|
||||
]
|
||||
[..]
|
||||
0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, 0x83_u8,
|
||||
0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8,
|
||||
][..]
|
||||
);
|
||||
}
|
||||
|
||||
@ -211,72 +185,15 @@ mod tests {
|
||||
assert_eq!(
|
||||
&buf[..],
|
||||
&[
|
||||
0x73_u8,
|
||||
0xde_u8,
|
||||
0xcf_u8,
|
||||
0xa5_u8,
|
||||
0x8a_u8,
|
||||
0xa2_u8,
|
||||
0xe8_u8,
|
||||
0x4f_u8,
|
||||
0x94_u8,
|
||||
0x77_u8,
|
||||
0x1a_u8,
|
||||
0x75_u8,
|
||||
0x73_u8,
|
||||
0x6b_u8,
|
||||
0xb8_u8,
|
||||
0x8b_u8,
|
||||
0xd3_u8,
|
||||
0xc7_u8,
|
||||
0xb3_u8,
|
||||
0x82_u8,
|
||||
0x70_u8,
|
||||
0xcf_u8,
|
||||
0xb5_u8,
|
||||
0x0c_u8,
|
||||
0xb3_u8,
|
||||
0x90_u8,
|
||||
0xed_u8,
|
||||
0x78_u8,
|
||||
0xb3_u8,
|
||||
0x05_u8,
|
||||
0x65_u8,
|
||||
0x6a_u8,
|
||||
0xf8_u8,
|
||||
0x14_u8,
|
||||
0x8e_u8,
|
||||
0x52_u8,
|
||||
0x45_u8,
|
||||
0x2b_u8,
|
||||
0x22_u8,
|
||||
0x16_u8,
|
||||
0xb2_u8,
|
||||
0xb8_u8,
|
||||
0x09_u8,
|
||||
0x8b_u8,
|
||||
0x76_u8,
|
||||
0x1f_u8,
|
||||
0xc6_u8,
|
||||
0x33_u8,
|
||||
0x60_u8,
|
||||
0x60_u8,
|
||||
0xa0_u8,
|
||||
0x9f_u8,
|
||||
0x76_u8,
|
||||
0x41_u8,
|
||||
0x5e_u8,
|
||||
0x9f_u8,
|
||||
0x71_u8,
|
||||
0xea_u8,
|
||||
0x47_u8,
|
||||
0xf9_u8,
|
||||
0xe9_u8,
|
||||
0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, 0x94_u8,
|
||||
0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, 0xd3_u8, 0xc7_u8,
|
||||
0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, 0xb3_u8, 0x90_u8, 0xed_u8,
|
||||
0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8,
|
||||
0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8,
|
||||
0x1f_u8, 0xc6_u8, 0x33_u8, 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8,
|
||||
0x5e_u8, 0x9f_u8, 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8,
|
||||
0x06_u8,
|
||||
0x43_u8,
|
||||
0x06_u8,
|
||||
]
|
||||
[..]
|
||||
][..]
|
||||
);
|
||||
|
||||
super::pbkdf2_hmac(
|
||||
@ -285,76 +202,20 @@ mod tests {
|
||||
1,
|
||||
MessageDigest::sha512(),
|
||||
&mut buf,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
&buf[..],
|
||||
&[
|
||||
0x71_u8,
|
||||
0xa0_u8,
|
||||
0xec_u8,
|
||||
0x84_u8,
|
||||
0x2a_u8,
|
||||
0xbd_u8,
|
||||
0x5c_u8,
|
||||
0x67_u8,
|
||||
0x8b_u8,
|
||||
0xcf_u8,
|
||||
0xd1_u8,
|
||||
0x45_u8,
|
||||
0xf0_u8,
|
||||
0x9d_u8,
|
||||
0x83_u8,
|
||||
0x52_u8,
|
||||
0x2f_u8,
|
||||
0x93_u8,
|
||||
0x36_u8,
|
||||
0x15_u8,
|
||||
0x60_u8,
|
||||
0x56_u8,
|
||||
0x3c_u8,
|
||||
0x4d_u8,
|
||||
0x0d_u8,
|
||||
0x63_u8,
|
||||
0xb8_u8,
|
||||
0x83_u8,
|
||||
0x29_u8,
|
||||
0x87_u8,
|
||||
0x10_u8,
|
||||
0x90_u8,
|
||||
0xe7_u8,
|
||||
0x66_u8,
|
||||
0x04_u8,
|
||||
0xa4_u8,
|
||||
0x9a_u8,
|
||||
0xf0_u8,
|
||||
0x8f_u8,
|
||||
0xe7_u8,
|
||||
0xc9_u8,
|
||||
0xf5_u8,
|
||||
0x71_u8,
|
||||
0x56_u8,
|
||||
0xc8_u8,
|
||||
0x79_u8,
|
||||
0x09_u8,
|
||||
0x96_u8,
|
||||
0xb2_u8,
|
||||
0x0f_u8,
|
||||
0x06_u8,
|
||||
0xbc_u8,
|
||||
0x53_u8,
|
||||
0x5e_u8,
|
||||
0x5a_u8,
|
||||
0xb5_u8,
|
||||
0x44_u8,
|
||||
0x0d_u8,
|
||||
0xf7_u8,
|
||||
0xe8_u8,
|
||||
0x78_u8,
|
||||
0x29_u8,
|
||||
0x6f_u8,
|
||||
0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, 0x8b_u8,
|
||||
0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, 0x2f_u8, 0x93_u8,
|
||||
0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, 0x0d_u8, 0x63_u8, 0xb8_u8,
|
||||
0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8,
|
||||
0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8,
|
||||
0x79_u8, 0x09_u8, 0x96_u8, 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8,
|
||||
0x5a_u8, 0xb5_u8, 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8,
|
||||
0xa7_u8,
|
||||
]
|
||||
[..]
|
||||
][..]
|
||||
);
|
||||
|
||||
super::pbkdf2_hmac(
|
||||
@ -363,76 +224,20 @@ mod tests {
|
||||
50,
|
||||
MessageDigest::sha512(),
|
||||
&mut buf,
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
&buf[..],
|
||||
&[
|
||||
0x01_u8,
|
||||
0x68_u8,
|
||||
0x71_u8,
|
||||
0xa4_u8,
|
||||
0xc4_u8,
|
||||
0xb7_u8,
|
||||
0x5f_u8,
|
||||
0x96_u8,
|
||||
0x85_u8,
|
||||
0x7f_u8,
|
||||
0xd2_u8,
|
||||
0xb9_u8,
|
||||
0xf8_u8,
|
||||
0xca_u8,
|
||||
0x28_u8,
|
||||
0x02_u8,
|
||||
0x3b_u8,
|
||||
0x30_u8,
|
||||
0xee_u8,
|
||||
0x2a_u8,
|
||||
0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, 0x85_u8,
|
||||
0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, 0x3b_u8, 0x30_u8,
|
||||
0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, 0xc8_u8, 0xc9_u8, 0x37_u8,
|
||||
0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8,
|
||||
0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8,
|
||||
0x00_u8, 0x56_u8, 0xc6_u8, 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8,
|
||||
0x4b_u8, 0x1a_u8, 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8,
|
||||
0x39_u8,
|
||||
0xf5_u8,
|
||||
0xad_u8,
|
||||
0xca_u8,
|
||||
0xc8_u8,
|
||||
0xc9_u8,
|
||||
0x37_u8,
|
||||
0x5f_u8,
|
||||
0x9b_u8,
|
||||
0xda_u8,
|
||||
0x1c_u8,
|
||||
0xcd_u8,
|
||||
0x1b_u8,
|
||||
0x6f_u8,
|
||||
0x0b_u8,
|
||||
0x2f_u8,
|
||||
0xc3_u8,
|
||||
0xad_u8,
|
||||
0xda_u8,
|
||||
0x50_u8,
|
||||
0x54_u8,
|
||||
0x12_u8,
|
||||
0xe7_u8,
|
||||
0x9d_u8,
|
||||
0x89_u8,
|
||||
0x00_u8,
|
||||
0x56_u8,
|
||||
0xc6_u8,
|
||||
0x2e_u8,
|
||||
0x52_u8,
|
||||
0x4c_u8,
|
||||
0x7d_u8,
|
||||
0x51_u8,
|
||||
0x15_u8,
|
||||
0x4b_u8,
|
||||
0x1a_u8,
|
||||
0x85_u8,
|
||||
0x34_u8,
|
||||
0x57_u8,
|
||||
0x5b_u8,
|
||||
0xd0_u8,
|
||||
0x2d_u8,
|
||||
0xee_u8,
|
||||
0x39_u8,
|
||||
]
|
||||
[..]
|
||||
][..]
|
||||
);
|
||||
}
|
||||
|
||||
@ -441,93 +246,19 @@ mod tests {
|
||||
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
|
||||
|
||||
let data = [
|
||||
143_u8,
|
||||
210_u8,
|
||||
75_u8,
|
||||
63_u8,
|
||||
214_u8,
|
||||
179_u8,
|
||||
155_u8,
|
||||
241_u8,
|
||||
242_u8,
|
||||
31_u8,
|
||||
154_u8,
|
||||
56_u8,
|
||||
198_u8,
|
||||
145_u8,
|
||||
192_u8,
|
||||
64_u8,
|
||||
2_u8,
|
||||
245_u8,
|
||||
167_u8,
|
||||
220_u8,
|
||||
55_u8,
|
||||
119_u8,
|
||||
233_u8,
|
||||
136_u8,
|
||||
139_u8,
|
||||
27_u8,
|
||||
71_u8,
|
||||
242_u8,
|
||||
119_u8,
|
||||
175_u8,
|
||||
65_u8,
|
||||
207_u8,
|
||||
143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
|
||||
56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
|
||||
233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
|
||||
];
|
||||
|
||||
|
||||
|
||||
let expected_key = vec![
|
||||
249_u8,
|
||||
115_u8,
|
||||
114_u8,
|
||||
97_u8,
|
||||
32_u8,
|
||||
213_u8,
|
||||
165_u8,
|
||||
146_u8,
|
||||
58_u8,
|
||||
87_u8,
|
||||
234_u8,
|
||||
3_u8,
|
||||
43_u8,
|
||||
250_u8,
|
||||
97_u8,
|
||||
114_u8,
|
||||
26_u8,
|
||||
98_u8,
|
||||
245_u8,
|
||||
246_u8,
|
||||
238_u8,
|
||||
177_u8,
|
||||
229_u8,
|
||||
161_u8,
|
||||
183_u8,
|
||||
224_u8,
|
||||
174_u8,
|
||||
3_u8,
|
||||
6_u8,
|
||||
244_u8,
|
||||
236_u8,
|
||||
255_u8,
|
||||
249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8, 58_u8, 87_u8, 234_u8,
|
||||
3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8, 98_u8, 245_u8, 246_u8, 238_u8, 177_u8,
|
||||
229_u8, 161_u8, 183_u8, 224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8,
|
||||
];
|
||||
let expected_iv = vec![
|
||||
4_u8,
|
||||
223_u8,
|
||||
153_u8,
|
||||
219_u8,
|
||||
28_u8,
|
||||
142_u8,
|
||||
234_u8,
|
||||
68_u8,
|
||||
227_u8,
|
||||
69_u8,
|
||||
98_u8,
|
||||
107_u8,
|
||||
208_u8,
|
||||
14_u8,
|
||||
236_u8,
|
||||
60_u8,
|
||||
4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
|
||||
107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
@ -537,7 +268,8 @@ mod tests {
|
||||
&data,
|
||||
Some(&salt),
|
||||
1,
|
||||
).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
super::KeyIvPair {
|
||||
key: expected_key,
|
||||
iv: Some(expected_iv),
|
||||
@ -546,14 +278,15 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "v110", ossl110))]
|
||||
#[cfg(any(ossl110))]
|
||||
fn scrypt() {
|
||||
use hex::ToHex;
|
||||
use hex;
|
||||
|
||||
let pass = "pleaseletmein";
|
||||
let salt = "SodiumChloride";
|
||||
let expected = "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\
|
||||
f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887";
|
||||
let expected =
|
||||
"7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\
|
||||
f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887";
|
||||
|
||||
let mut actual = [0; 64];
|
||||
super::scrypt(
|
||||
@ -564,7 +297,8 @@ mod tests {
|
||||
1,
|
||||
0,
|
||||
&mut actual,
|
||||
).unwrap();
|
||||
assert_eq!((&actual[..]).to_hex(), expected);
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(hex::encode(&actual[..]), expected);
|
||||
}
|
||||
}
|
||||
|
||||
389
openssl/src/pkcs7.rs
Normal file
389
openssl/src/pkcs7.rs
Normal file
@ -0,0 +1,389 @@
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::c_int;
|
||||
use pkey::{HasPrivate, PKeyRef};
|
||||
use stack::StackRef;
|
||||
use std::ptr;
|
||||
use symm::Cipher;
|
||||
use x509::store::X509StoreRef;
|
||||
use x509::{X509Ref, X509};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::PKCS7;
|
||||
fn drop = ffi::PKCS7_free;
|
||||
|
||||
/// A PKCS#7 structure.
|
||||
///
|
||||
/// Contains signed and/or encrypted data.
|
||||
pub struct Pkcs7;
|
||||
|
||||
/// Reference to `Pkcs7`
|
||||
pub struct Pkcs7Ref;
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct Pkcs7Flags: c_int {
|
||||
const TEXT = ffi::PKCS7_TEXT;
|
||||
const NOCERTS = ffi::PKCS7_NOCERTS;
|
||||
const NOSIGS = ffi::PKCS7_NOSIGS;
|
||||
const NOCHAIN = ffi::PKCS7_NOCHAIN;
|
||||
const NOINTERN = ffi::PKCS7_NOINTERN;
|
||||
const NOVERIFY = ffi::PKCS7_NOVERIFY;
|
||||
const DETACHED = ffi::PKCS7_DETACHED;
|
||||
const BINARY = ffi::PKCS7_BINARY;
|
||||
const NOATTR = ffi::PKCS7_NOATTR;
|
||||
const NOSMIMECAP = ffi::PKCS7_NOSMIMECAP;
|
||||
const NOOLDMIMETYPE = ffi::PKCS7_NOOLDMIMETYPE;
|
||||
const CRLFEOL = ffi::PKCS7_CRLFEOL;
|
||||
const STREAM = ffi::PKCS7_STREAM;
|
||||
const NOCRL = ffi::PKCS7_NOCRL;
|
||||
const PARTIAL = ffi::PKCS7_PARTIAL;
|
||||
const REUSE_DIGEST = ffi::PKCS7_REUSE_DIGEST;
|
||||
#[cfg(not(any(ossl101, ossl102, libressl)))]
|
||||
const NO_DUAL_CONTENT = ffi::PKCS7_NO_DUAL_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
impl Pkcs7 {
|
||||
from_pem! {
|
||||
/// Deserializes a PEM-encoded PKCS#7 signature
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN PKCS7-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_PKCS7`].
|
||||
///
|
||||
/// [`PEM_read_bio_PKCS7`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_PKCS7.html
|
||||
from_pem,
|
||||
Pkcs7,
|
||||
ffi::PEM_read_bio_PKCS7
|
||||
}
|
||||
|
||||
/// Parses a message in S/MIME format.
|
||||
///
|
||||
/// Returns the loaded signature, along with the cleartext message (if
|
||||
/// available).
|
||||
///
|
||||
/// This corresponds to [`SMIME_read_PKCS7`].
|
||||
///
|
||||
/// [`SMIME_read_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_read_PKCS7.html
|
||||
pub fn from_smime(input: &[u8]) -> Result<(Pkcs7, Option<Vec<u8>>), ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
let input_bio = MemBioSlice::new(input)?;
|
||||
let mut bcont_bio = ptr::null_mut();
|
||||
unsafe {
|
||||
let pkcs7 =
|
||||
cvt_p(ffi::SMIME_read_PKCS7(input_bio.as_ptr(), &mut bcont_bio)).map(Pkcs7)?;
|
||||
let out = if !bcont_bio.is_null() {
|
||||
let bcont_bio = MemBio::from_ptr(bcont_bio);
|
||||
Some(bcont_bio.get_buf().to_vec())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok((pkcs7, out))
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates and returns a PKCS#7 `envelopedData` structure.
|
||||
///
|
||||
/// `certs` is a list of recipient certificates. `input` is the content to be
|
||||
/// encrypted. `cipher` is the symmetric cipher to use. `flags` is an optional
|
||||
/// set of flags.
|
||||
///
|
||||
/// This corresponds to [`PKCS7_encrypt`].
|
||||
///
|
||||
/// [`PKCS7_encrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_encrypt.html
|
||||
pub fn encrypt(
|
||||
certs: &StackRef<X509>,
|
||||
input: &[u8],
|
||||
cipher: Cipher,
|
||||
flags: Pkcs7Flags,
|
||||
) -> Result<Pkcs7, ErrorStack> {
|
||||
let input_bio = MemBioSlice::new(input)?;
|
||||
|
||||
unsafe {
|
||||
cvt_p(ffi::PKCS7_encrypt(
|
||||
certs.as_ptr(),
|
||||
input_bio.as_ptr(),
|
||||
cipher.as_ptr(),
|
||||
flags.bits,
|
||||
))
|
||||
.map(Pkcs7)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates and returns a PKCS#7 `signedData` structure.
|
||||
///
|
||||
/// `signcert` is the certificate to sign with, `pkey` is the corresponding
|
||||
/// private key. `certs` is an optional additional set of certificates to
|
||||
/// include in the PKCS#7 structure (for example any intermediate CAs in the
|
||||
/// chain).
|
||||
///
|
||||
/// This corresponds to [`PKCS7_sign`].
|
||||
///
|
||||
/// [`PKCS7_sign`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_sign.html
|
||||
pub fn sign<PT>(
|
||||
signcert: &X509Ref,
|
||||
pkey: &PKeyRef<PT>,
|
||||
certs: &StackRef<X509>,
|
||||
input: &[u8],
|
||||
flags: Pkcs7Flags,
|
||||
) -> Result<Pkcs7, ErrorStack>
|
||||
where
|
||||
PT: HasPrivate,
|
||||
{
|
||||
let input_bio = MemBioSlice::new(input)?;
|
||||
unsafe {
|
||||
cvt_p(ffi::PKCS7_sign(
|
||||
signcert.as_ptr(),
|
||||
pkey.as_ptr(),
|
||||
certs.as_ptr(),
|
||||
input_bio.as_ptr(),
|
||||
flags.bits,
|
||||
))
|
||||
.map(Pkcs7)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Pkcs7Ref {
|
||||
/// Converts PKCS#7 structure to S/MIME format
|
||||
///
|
||||
/// This corresponds to [`SMIME_write_PKCS7`].
|
||||
///
|
||||
/// [`SMIME_write_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_write_PKCS7.html
|
||||
pub fn to_smime(&self, input: &[u8], flags: Pkcs7Flags) -> Result<Vec<u8>, ErrorStack> {
|
||||
let input_bio = MemBioSlice::new(input)?;
|
||||
let output = MemBio::new()?;
|
||||
unsafe {
|
||||
cvt(ffi::SMIME_write_PKCS7(
|
||||
output.as_ptr(),
|
||||
self.as_ptr(),
|
||||
input_bio.as_ptr(),
|
||||
flags.bits,
|
||||
))
|
||||
.map(|_| output.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
to_pem! {
|
||||
/// Serializes the data into a PEM-encoded PKCS#7 structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN PKCS7-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_PKCS7`].
|
||||
///
|
||||
/// [`PEM_write_bio_PKCS7`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS7.html
|
||||
to_pem,
|
||||
ffi::PEM_write_bio_PKCS7
|
||||
}
|
||||
|
||||
/// Decrypts data using the provided private key.
|
||||
///
|
||||
/// `pkey` is the recipient's private key, and `cert` is the recipient's
|
||||
/// certificate.
|
||||
///
|
||||
/// Returns the decrypted message.
|
||||
///
|
||||
/// This corresponds to [`PKCS7_decrypt`].
|
||||
///
|
||||
/// [`PKCS7_decrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_decrypt.html
|
||||
pub fn decrypt<PT>(
|
||||
&self,
|
||||
pkey: &PKeyRef<PT>,
|
||||
cert: &X509Ref,
|
||||
flags: Pkcs7Flags,
|
||||
) -> Result<Vec<u8>, ErrorStack>
|
||||
where
|
||||
PT: HasPrivate,
|
||||
{
|
||||
let output = MemBio::new()?;
|
||||
|
||||
unsafe {
|
||||
cvt(ffi::PKCS7_decrypt(
|
||||
self.as_ptr(),
|
||||
pkey.as_ptr(),
|
||||
cert.as_ptr(),
|
||||
output.as_ptr(),
|
||||
flags.bits,
|
||||
))
|
||||
.map(|_| output.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifies the PKCS#7 `signedData` structure contained by `&self`.
|
||||
///
|
||||
/// `certs` is a set of certificates in which to search for the signer's
|
||||
/// certificate. `store` is a trusted certificate store (used for chain
|
||||
/// verification). `indata` is the signed data if the content is not present
|
||||
/// in `&self`. The content is written to `out` if it is not `None`.
|
||||
///
|
||||
/// This corresponds to [`PKCS7_verify`].
|
||||
///
|
||||
/// [`PKCS7_verify`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_verify.html
|
||||
pub fn verify(
|
||||
&self,
|
||||
certs: &StackRef<X509>,
|
||||
store: &X509StoreRef,
|
||||
indata: Option<&[u8]>,
|
||||
out: Option<&mut Vec<u8>>,
|
||||
flags: Pkcs7Flags,
|
||||
) -> Result<(), ErrorStack> {
|
||||
let out_bio = MemBio::new()?;
|
||||
|
||||
let indata_bio = match indata {
|
||||
Some(data) => Some(MemBioSlice::new(data)?),
|
||||
None => None,
|
||||
};
|
||||
let indata_bio_ptr = indata_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
|
||||
unsafe {
|
||||
cvt(ffi::PKCS7_verify(
|
||||
self.as_ptr(),
|
||||
certs.as_ptr(),
|
||||
store.as_ptr(),
|
||||
indata_bio_ptr,
|
||||
out_bio.as_ptr(),
|
||||
flags.bits,
|
||||
))
|
||||
.map(|_| ())?
|
||||
}
|
||||
|
||||
if let Some(data) = out {
|
||||
data.clear();
|
||||
data.extend_from_slice(out_bio.get_buf());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pkcs7::{Pkcs7, Pkcs7Flags};
|
||||
use pkey::PKey;
|
||||
use stack::Stack;
|
||||
use symm::Cipher;
|
||||
use x509::store::X509StoreBuilder;
|
||||
use x509::X509;
|
||||
|
||||
#[test]
|
||||
fn encrypt_decrypt_test() {
|
||||
let cert = include_bytes!("../test/certs.pem");
|
||||
let cert = X509::from_pem(cert).unwrap();
|
||||
let mut certs = Stack::new().unwrap();
|
||||
certs.push(cert.clone()).unwrap();
|
||||
let message: String = String::from("foo");
|
||||
let cypher = Cipher::des_ede3_cbc();
|
||||
let flags = Pkcs7Flags::STREAM;
|
||||
let pkey = include_bytes!("../test/key.pem");
|
||||
let pkey = PKey::private_key_from_pem(pkey).unwrap();
|
||||
|
||||
let pkcs7 =
|
||||
Pkcs7::encrypt(&certs, message.as_bytes(), cypher, flags).expect("should succeed");
|
||||
|
||||
let encrypted = pkcs7
|
||||
.to_smime(message.as_bytes(), flags)
|
||||
.expect("should succeed");
|
||||
|
||||
let (pkcs7_decoded, _) = Pkcs7::from_smime(encrypted.as_slice()).expect("should succeed");
|
||||
|
||||
let decoded = pkcs7_decoded
|
||||
.decrypt(&pkey, &cert, Pkcs7Flags::empty())
|
||||
.expect("should succeed");
|
||||
|
||||
assert_eq!(decoded, message.into_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_verify_test_detached() {
|
||||
let cert = include_bytes!("../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).unwrap();
|
||||
let certs = Stack::new().unwrap();
|
||||
let message: String = String::from("foo");
|
||||
let flags = Pkcs7Flags::STREAM | Pkcs7Flags::DETACHED;
|
||||
let pkey = include_bytes!("../test/key.pem");
|
||||
let pkey = PKey::private_key_from_pem(pkey).unwrap();
|
||||
let mut store_builder = X509StoreBuilder::new().expect("should succeed");
|
||||
|
||||
let root_ca = include_bytes!("../test/root-ca.pem");
|
||||
let root_ca = X509::from_pem(root_ca).unwrap();
|
||||
store_builder.add_cert(root_ca).expect("should succeed");
|
||||
|
||||
let store = store_builder.build();
|
||||
|
||||
let pkcs7 =
|
||||
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
||||
|
||||
let signed = pkcs7
|
||||
.to_smime(message.as_bytes(), flags)
|
||||
.expect("should succeed");
|
||||
println!("{:?}", String::from_utf8(signed.clone()).unwrap());
|
||||
let (pkcs7_decoded, content) =
|
||||
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
||||
|
||||
let mut output = Vec::new();
|
||||
pkcs7_decoded
|
||||
.verify(
|
||||
&certs,
|
||||
&store,
|
||||
Some(message.as_bytes()),
|
||||
Some(&mut output),
|
||||
flags,
|
||||
)
|
||||
.expect("should succeed");
|
||||
|
||||
assert_eq!(message.clone().into_bytes(), output);
|
||||
assert_eq!(
|
||||
message.clone().into_bytes(),
|
||||
content.expect("should be non-empty")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_verify_test_normal() {
|
||||
let cert = include_bytes!("../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).unwrap();
|
||||
let certs = Stack::new().unwrap();
|
||||
let message: String = String::from("foo");
|
||||
let flags = Pkcs7Flags::STREAM;
|
||||
let pkey = include_bytes!("../test/key.pem");
|
||||
let pkey = PKey::private_key_from_pem(pkey).unwrap();
|
||||
let mut store_builder = X509StoreBuilder::new().expect("should succeed");
|
||||
|
||||
let root_ca = include_bytes!("../test/root-ca.pem");
|
||||
let root_ca = X509::from_pem(root_ca).unwrap();
|
||||
store_builder.add_cert(root_ca).expect("should succeed");
|
||||
|
||||
let store = store_builder.build();
|
||||
|
||||
let pkcs7 =
|
||||
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
||||
|
||||
let signed = pkcs7
|
||||
.to_smime(message.as_bytes(), flags)
|
||||
.expect("should succeed");
|
||||
|
||||
let (pkcs7_decoded, content) =
|
||||
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
||||
|
||||
let mut output = Vec::new();
|
||||
pkcs7_decoded
|
||||
.verify(&certs, &store, None, Some(&mut output), flags)
|
||||
.expect("should succeed");
|
||||
|
||||
assert_eq!(message.clone().into_bytes(), output);
|
||||
assert!(content.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_from_smime() {
|
||||
let input = String::from("Invalid SMIME Message");
|
||||
let result = Pkcs7::from_smime(input.as_bytes());
|
||||
|
||||
assert_eq!(result.is_err(), true)
|
||||
}
|
||||
}
|
||||
@ -1,30 +1,149 @@
|
||||
use libc::{c_void, c_char, c_int, size_t};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::ffi::CString;
|
||||
//! Public/private key processing.
|
||||
//!
|
||||
//! Asymmetric public key algorithms solve the problem of establishing and sharing
|
||||
//! secret keys to securely send and receive messages.
|
||||
//! This system uses a pair of keys: a public key, which can be freely
|
||||
//! distributed, and a private key, which is kept to oneself. An entity may
|
||||
//! encrypt information using a user's public key. The encrypted information can
|
||||
//! only be deciphered using that user's private key.
|
||||
//!
|
||||
//! This module offers support for five popular algorithms:
|
||||
//!
|
||||
//! * RSA
|
||||
//!
|
||||
//! * DSA
|
||||
//!
|
||||
//! * Diffie-Hellman
|
||||
//!
|
||||
//! * Elliptic Curves
|
||||
//!
|
||||
//! * HMAC
|
||||
//!
|
||||
//! These algorithms rely on hard mathematical problems - namely integer factorization,
|
||||
//! discrete logarithms, and elliptic curve relationships - that currently do not
|
||||
//! yield efficient solutions. This property ensures the security of these
|
||||
//! cryptographic algorithms.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! Generate a 2048-bit RSA public/private key pair and print the public key.
|
||||
//!
|
||||
//! ```rust
|
||||
//!
|
||||
//! extern crate openssl;
|
||||
//!
|
||||
//! use openssl::rsa::Rsa;
|
||||
//! use openssl::pkey::PKey;
|
||||
//! use std::str;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let rsa = Rsa::generate(2048).unwrap();
|
||||
//! let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
//!
|
||||
//! let pub_key: Vec<u8> = pkey.public_key_to_pem().unwrap();
|
||||
//! println!("{:?}", str::from_utf8(pub_key.as_slice()).unwrap());
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBioSlice;
|
||||
use dh::Dh;
|
||||
use dsa::Dsa;
|
||||
use ec::EcKey;
|
||||
use rsa::{Rsa, Padding};
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb, invoke_passwd_cb_old};
|
||||
use rsa::Rsa;
|
||||
use util::{invoke_passwd_cb, CallbackState};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
/// A tag type indicating that a key only has parameters.
|
||||
pub enum Params {}
|
||||
|
||||
/// A tag type indicating that a key only has public components.
|
||||
pub enum Public {}
|
||||
|
||||
/// A tag type indicating that a key has private components.
|
||||
pub enum Private {}
|
||||
|
||||
/// An identifier of a kind of key.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Id(c_int);
|
||||
|
||||
impl Id {
|
||||
/// Creates a `Id` from an integer representation.
|
||||
pub fn from_raw(value: c_int) -> Id {
|
||||
Id(value)
|
||||
}
|
||||
|
||||
/// Returns the integer representation of the `Id`.
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub const RSA: Id = Id(ffi::EVP_PKEY_RSA);
|
||||
pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC);
|
||||
pub const DSA: Id = Id(ffi::EVP_PKEY_DSA);
|
||||
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
|
||||
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
|
||||
#[cfg(ossl111)]
|
||||
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
|
||||
}
|
||||
|
||||
/// A trait indicating that a key has parameters.
|
||||
pub unsafe trait HasParams {}
|
||||
|
||||
unsafe impl HasParams for Params {}
|
||||
|
||||
unsafe impl<T> HasParams for T where T: HasPublic {}
|
||||
|
||||
/// A trait indicating that a key has public components.
|
||||
pub unsafe trait HasPublic {}
|
||||
|
||||
unsafe impl HasPublic for Public {}
|
||||
|
||||
unsafe impl<T> HasPublic for T where T: HasPrivate {}
|
||||
|
||||
/// A trait indicating that a key has private components.
|
||||
pub unsafe trait HasPrivate {}
|
||||
|
||||
unsafe impl HasPrivate for Private {}
|
||||
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::EVP_PKEY;
|
||||
fn drop = ffi::EVP_PKEY_free;
|
||||
|
||||
pub struct PKey;
|
||||
pub struct PKeyRef;
|
||||
/// A public or private key.
|
||||
pub struct PKey<T>;
|
||||
/// Reference to `PKey`.
|
||||
pub struct PKeyRef<T>;
|
||||
}
|
||||
|
||||
impl PKeyRef {
|
||||
impl<T> ToOwned for PKeyRef<T> {
|
||||
type Owned = PKey<T>;
|
||||
|
||||
fn to_owned(&self) -> PKey<T> {
|
||||
unsafe {
|
||||
EVP_PKEY_up_ref(self.as_ptr());
|
||||
PKey::from_ptr(self.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PKeyRef<T> {
|
||||
/// Returns a copy of the internal RSA key.
|
||||
pub fn rsa(&self) -> Result<Rsa, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_get1_RSA`].
|
||||
///
|
||||
/// [`EVP_PKEY_get1_RSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_RSA.html
|
||||
pub fn rsa(&self) -> Result<Rsa<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = cvt_p(ffi::EVP_PKEY_get1_RSA(self.as_ptr()))?;
|
||||
Ok(Rsa::from_ptr(rsa))
|
||||
@ -32,7 +151,11 @@ impl PKeyRef {
|
||||
}
|
||||
|
||||
/// Returns a copy of the internal DSA key.
|
||||
pub fn dsa(&self) -> Result<Dsa, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_get1_DSA`].
|
||||
///
|
||||
/// [`EVP_PKEY_get1_DSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_DSA.html
|
||||
pub fn dsa(&self) -> Result<Dsa<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let dsa = cvt_p(ffi::EVP_PKEY_get1_DSA(self.as_ptr()))?;
|
||||
Ok(Dsa::from_ptr(dsa))
|
||||
@ -40,7 +163,11 @@ impl PKeyRef {
|
||||
}
|
||||
|
||||
/// Returns a copy of the internal DH key.
|
||||
pub fn dh(&self) -> Result<Dh, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_get1_DH`].
|
||||
///
|
||||
/// [`EVP_PKEY_get1_DH`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_DH.html
|
||||
pub fn dh(&self) -> Result<Dh<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let dh = cvt_p(ffi::EVP_PKEY_get1_DH(self.as_ptr()))?;
|
||||
Ok(Dh::from_ptr(dh))
|
||||
@ -48,18 +175,61 @@ impl PKeyRef {
|
||||
}
|
||||
|
||||
/// Returns a copy of the internal elliptic curve key.
|
||||
pub fn ec_key(&self) -> Result<EcKey, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_get1_EC_KEY`].
|
||||
///
|
||||
/// [`EVP_PKEY_get1_EC_KEY`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_EC_KEY.html
|
||||
pub fn ec_key(&self) -> Result<EcKey<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let ec_key = cvt_p(ffi::EVP_PKEY_get1_EC_KEY(self.as_ptr()))?;
|
||||
Ok(EcKey::from_ptr(ec_key))
|
||||
}
|
||||
}
|
||||
|
||||
public_key_to_pem!(ffi::PEM_write_bio_PUBKEY);
|
||||
private_key_to_pem!(ffi::PEM_write_bio_PKCS8PrivateKey);
|
||||
/// Returns the `Id` that represents the type of this key.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_id`].
|
||||
///
|
||||
/// [`EVP_PKEY_id`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_id.html
|
||||
pub fn id(&self) -> Id {
|
||||
unsafe { Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) }
|
||||
}
|
||||
|
||||
private_key_to_der!(ffi::i2d_PrivateKey);
|
||||
public_key_to_der!(ffi::i2d_PUBKEY);
|
||||
/// Returns the maximum size of a signature in bytes.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_size`].
|
||||
///
|
||||
/// [`EVP_PKEY_size`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_size.html
|
||||
pub fn size(&self) -> usize {
|
||||
unsafe { ffi::EVP_PKEY_size(self.as_ptr()) as usize }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PKeyRef<T>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
to_pem! {
|
||||
/// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_PUBKEY`].
|
||||
///
|
||||
/// [`PEM_write_bio_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_PUBKEY.html
|
||||
public_key_to_pem,
|
||||
ffi::PEM_write_bio_PUBKEY
|
||||
}
|
||||
|
||||
to_der! {
|
||||
/// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// This corresponds to [`i2d_PUBKEY`].
|
||||
///
|
||||
/// [`i2d_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_PUBKEY.html
|
||||
public_key_to_der,
|
||||
ffi::i2d_PUBKEY
|
||||
}
|
||||
|
||||
/// Returns the size of the key.
|
||||
///
|
||||
@ -70,17 +240,65 @@ impl PKeyRef {
|
||||
}
|
||||
|
||||
/// Compares the public component of this key with another.
|
||||
pub fn public_eq(&self, other: &PKeyRef) -> bool {
|
||||
pub fn public_eq<U>(&self, other: &PKeyRef<U>) -> bool
|
||||
where
|
||||
U: HasPublic,
|
||||
{
|
||||
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
|
||||
}
|
||||
}
|
||||
|
||||
impl PKey {
|
||||
impl<T> PKeyRef<T>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
private_key_to_pem! {
|
||||
/// Serializes the private key to a PEM-encoded PKCS#8 PrivateKeyInfo structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_PKCS8PrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_PKCS8PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS8PrivateKey.html
|
||||
private_key_to_pem_pkcs8,
|
||||
/// Serializes the private key to a PEM-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
|
||||
///
|
||||
/// The output will have a header of `-----BEGIN ENCRYPTED PRIVATE KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_write_bio_PKCS8PrivateKey`].
|
||||
///
|
||||
/// [`PEM_write_bio_PKCS8PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS8PrivateKey.html
|
||||
private_key_to_pem_pkcs8_passphrase,
|
||||
ffi::PEM_write_bio_PKCS8PrivateKey
|
||||
}
|
||||
|
||||
to_der! {
|
||||
/// Serializes the private key to a DER-encoded key type specific format.
|
||||
///
|
||||
/// This corresponds to [`i2d_PrivateKey`].
|
||||
///
|
||||
/// [`i2d_PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/i2d_PrivateKey.html
|
||||
private_key_to_der,
|
||||
ffi::i2d_PrivateKey
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for PKey<T> {
|
||||
fn clone(&self) -> PKey<T> {
|
||||
PKeyRef::to_owned(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PKey<T> {
|
||||
/// Creates a new `PKey` containing an RSA key.
|
||||
pub fn from_rsa(rsa: Rsa) -> Result<PKey, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_assign_RSA`].
|
||||
///
|
||||
/// [`EVP_PKEY_assign_RSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_RSA.html
|
||||
pub fn from_rsa(rsa: Rsa<T>) -> Result<PKey<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::EVP_PKEY_new())?;
|
||||
let pkey = PKey(evp);
|
||||
let pkey = PKey::from_ptr(evp);
|
||||
cvt(ffi::EVP_PKEY_assign(
|
||||
pkey.0,
|
||||
ffi::EVP_PKEY_RSA,
|
||||
@ -92,10 +310,14 @@ impl PKey {
|
||||
}
|
||||
|
||||
/// Creates a new `PKey` containing a DSA key.
|
||||
pub fn from_dsa(dsa: Dsa) -> Result<PKey, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_assign_DSA`].
|
||||
///
|
||||
/// [`EVP_PKEY_assign_DSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_DSA.html
|
||||
pub fn from_dsa(dsa: Dsa<T>) -> Result<PKey<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::EVP_PKEY_new())?;
|
||||
let pkey = PKey(evp);
|
||||
let pkey = PKey::from_ptr(evp);
|
||||
cvt(ffi::EVP_PKEY_assign(
|
||||
pkey.0,
|
||||
ffi::EVP_PKEY_DSA,
|
||||
@ -107,10 +329,14 @@ impl PKey {
|
||||
}
|
||||
|
||||
/// Creates a new `PKey` containing a Diffie-Hellman key.
|
||||
pub fn from_dh(dh: Dh) -> Result<PKey, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_assign_DH`].
|
||||
///
|
||||
/// [`EVP_PKEY_assign_DH`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_DH.html
|
||||
pub fn from_dh(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::EVP_PKEY_new())?;
|
||||
let pkey = PKey(evp);
|
||||
let pkey = PKey::from_ptr(evp);
|
||||
cvt(ffi::EVP_PKEY_assign(
|
||||
pkey.0,
|
||||
ffi::EVP_PKEY_DH,
|
||||
@ -122,10 +348,14 @@ impl PKey {
|
||||
}
|
||||
|
||||
/// Creates a new `PKey` containing an elliptic curve key.
|
||||
pub fn from_ec_key(ec_key: EcKey) -> Result<PKey, ErrorStack> {
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_assign_EC_KEY`].
|
||||
///
|
||||
/// [`EVP_PKEY_assign_EC_KEY`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_EC_KEY.html
|
||||
pub fn from_ec_key(ec_key: EcKey<T>) -> Result<PKey<T>, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::EVP_PKEY_new())?;
|
||||
let pkey = PKey(evp);
|
||||
let pkey = PKey::from_ptr(evp);
|
||||
cvt(ffi::EVP_PKEY_assign(
|
||||
pkey.0,
|
||||
ffi::EVP_PKEY_EC,
|
||||
@ -135,12 +365,15 @@ impl PKey {
|
||||
Ok(pkey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PKey<Private> {
|
||||
/// Creates a new `PKey` containing an HMAC key.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// To compute HMAC values, use the `sign` module.
|
||||
pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> {
|
||||
pub fn hmac(key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(key.len() <= c_int::max_value() as usize);
|
||||
let key = cvt_p(ffi::EVP_PKEY_new_mac_key(
|
||||
@ -149,21 +382,157 @@ impl PKey {
|
||||
key.as_ptr() as *const _,
|
||||
key.len() as c_int,
|
||||
))?;
|
||||
Ok(PKey(key))
|
||||
Ok(PKey::from_ptr(key))
|
||||
}
|
||||
}
|
||||
|
||||
private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey);
|
||||
public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY);
|
||||
public_key_from_der!(PKey, ffi::d2i_PUBKEY);
|
||||
private_key_from_der!(PKey, ffi::d2i_AutoPrivateKey);
|
||||
/// Creates a new `PKey` containing a CMAC key.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0 or newer.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// To compute CMAC values, use the `sign` module.
|
||||
#[cfg(ossl110)]
|
||||
pub fn cmac(cipher: &::symm::Cipher, key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
assert!(key.len() <= c_int::max_value() as usize);
|
||||
let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(
|
||||
ffi::EVP_PKEY_CMAC,
|
||||
ptr::null_mut(),
|
||||
))?;
|
||||
|
||||
let ret = (|| {
|
||||
cvt(ffi::EVP_PKEY_keygen_init(kctx))?;
|
||||
|
||||
// Set cipher for cmac
|
||||
cvt(ffi::EVP_PKEY_CTX_ctrl(
|
||||
kctx,
|
||||
-1,
|
||||
ffi::EVP_PKEY_OP_KEYGEN,
|
||||
ffi::EVP_PKEY_CTRL_CIPHER,
|
||||
0,
|
||||
cipher.as_ptr() as *mut _,
|
||||
))?;
|
||||
|
||||
// Set the key data
|
||||
cvt(ffi::EVP_PKEY_CTX_ctrl(
|
||||
kctx,
|
||||
-1,
|
||||
ffi::EVP_PKEY_OP_KEYGEN,
|
||||
ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
|
||||
key.len() as c_int,
|
||||
key.as_ptr() as *mut _,
|
||||
))?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
if let Err(e) = ret {
|
||||
// Free memory
|
||||
ffi::EVP_PKEY_CTX_free(kctx);
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// Generate key
|
||||
let mut key = ptr::null_mut();
|
||||
let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key));
|
||||
|
||||
// Free memory
|
||||
ffi::EVP_PKEY_CTX_free(kctx);
|
||||
|
||||
if let Err(e) = ret {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
Ok(PKey::from_ptr(key))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
fn generate_eddsa(nid: c_int) -> Result<PKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(nid, ptr::null_mut()))?;
|
||||
let ret = cvt(ffi::EVP_PKEY_keygen_init(kctx));
|
||||
if let Err(e) = ret {
|
||||
ffi::EVP_PKEY_CTX_free(kctx);
|
||||
return Err(e);
|
||||
}
|
||||
let mut key = ptr::null_mut();
|
||||
let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key));
|
||||
|
||||
ffi::EVP_PKEY_CTX_free(kctx);
|
||||
|
||||
if let Err(e) = ret {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
Ok(PKey::from_ptr(key))
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a new private Ed25519 key
|
||||
#[cfg(ossl111)]
|
||||
pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
|
||||
PKey::generate_eddsa(ffi::EVP_PKEY_ED25519)
|
||||
}
|
||||
|
||||
/// Generates a new private Ed448 key
|
||||
#[cfg(ossl111)]
|
||||
pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> {
|
||||
PKey::generate_eddsa(ffi::EVP_PKEY_ED448)
|
||||
}
|
||||
|
||||
private_key_from_pem! {
|
||||
/// Deserializes a private key from a PEM-encoded key type specific format.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_PrivateKey`].
|
||||
///
|
||||
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
|
||||
private_key_from_pem,
|
||||
|
||||
/// Deserializes a private key from a PEM-encoded encrypted key type specific format.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_PrivateKey`].
|
||||
///
|
||||
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
|
||||
private_key_from_pem_passphrase,
|
||||
|
||||
/// Deserializes a private key from a PEM-encoded encrypted key type specific format.
|
||||
///
|
||||
/// The callback should fill the password into the provided buffer and return its length.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_PrivateKey`].
|
||||
///
|
||||
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
|
||||
private_key_from_pem_callback,
|
||||
PKey<Private>,
|
||||
ffi::PEM_read_bio_PrivateKey
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Decodes a DER-encoded private key.
|
||||
///
|
||||
/// This function will automatically attempt to detect the underlying key format, and
|
||||
/// supports the unencrypted PKCS#8 PrivateKeyInfo structures as well as key type specific
|
||||
/// formats.
|
||||
///
|
||||
/// This corresponds to [`d2i_AutoPrivateKey`].
|
||||
///
|
||||
/// [`d2i_AutoPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_AutoPrivateKey.html
|
||||
private_key_from_der,
|
||||
PKey<Private>,
|
||||
ffi::d2i_AutoPrivateKey
|
||||
}
|
||||
|
||||
/// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password
|
||||
/// if the key is encrpyted.
|
||||
///
|
||||
/// The callback should copy the password into the provided buffer and return the number of
|
||||
/// bytes written.
|
||||
pub fn private_key_from_pkcs8_callback<F>(der: &[u8], callback: F) -> Result<PKey, ErrorStack>
|
||||
pub fn private_key_from_pkcs8_callback<F>(
|
||||
der: &[u8],
|
||||
callback: F,
|
||||
) -> Result<PKey<Private>, ErrorStack>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>,
|
||||
{
|
||||
@ -176,7 +545,8 @@ impl PKey {
|
||||
ptr::null_mut(),
|
||||
Some(invoke_passwd_cb::<F>),
|
||||
&mut cb as *mut _ as *mut _,
|
||||
)).map(PKey)
|
||||
))
|
||||
.map(|p| PKey::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +559,7 @@ impl PKey {
|
||||
pub fn private_key_from_pkcs8_passphrase(
|
||||
der: &[u8],
|
||||
passphrase: &[u8],
|
||||
) -> Result<PKey, ErrorStack> {
|
||||
) -> Result<PKey<Private>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let bio = MemBioSlice::new(der)?;
|
||||
@ -199,114 +569,62 @@ impl PKey {
|
||||
ptr::null_mut(),
|
||||
None,
|
||||
passphrase.as_ptr() as *const _ as *mut _,
|
||||
)).map(PKey)
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
|
||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
|
||||
where
|
||||
F: FnOnce(&mut [c_char]) -> usize,
|
||||
{
|
||||
ffi::init();
|
||||
let mut cb = CallbackState::new(pass_cb);
|
||||
let mem_bio = MemBioSlice::new(buf)?;
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::PEM_read_bio_PrivateKey(
|
||||
mem_bio.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
Some(invoke_passwd_cb_old::<F>),
|
||||
&mut cb as *mut _ as *mut c_void,
|
||||
))?;
|
||||
Ok(PKey::from_ptr(evp))
|
||||
))
|
||||
.map(|p| PKey::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::EVP_PKEY_CTX;
|
||||
fn drop = ffi::EVP_PKEY_CTX_free;
|
||||
impl PKey<Public> {
|
||||
from_pem! {
|
||||
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
|
||||
///
|
||||
/// This corresponds to [`PEM_read_bio_PUBKEY`].
|
||||
///
|
||||
/// [`PEM_read_bio_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_PUBKEY.html
|
||||
public_key_from_pem,
|
||||
PKey<Public>,
|
||||
ffi::PEM_read_bio_PUBKEY
|
||||
}
|
||||
|
||||
pub struct PKeyCtx;
|
||||
pub struct PKeyCtxRef;
|
||||
}
|
||||
|
||||
impl PKeyCtx {
|
||||
pub fn from_pkey(pkey: &PKeyRef) -> Result<PKeyCtx, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
|
||||
Ok(PKeyCtx(evp))
|
||||
}
|
||||
from_der! {
|
||||
/// Decodes a DER-encoded SubjectPublicKeyInfo structure.
|
||||
///
|
||||
/// This corresponds to [`d2i_PUBKEY`].
|
||||
///
|
||||
/// [`d2i_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_PUBKEY.html
|
||||
public_key_from_der,
|
||||
PKey<Public>,
|
||||
ffi::d2i_PUBKEY
|
||||
}
|
||||
}
|
||||
|
||||
impl PKeyCtxRef {
|
||||
pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
|
||||
self.as_ptr(),
|
||||
pad.as_raw(),
|
||||
))?;
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl270))] {
|
||||
use ffi::EVP_PKEY_up_ref;
|
||||
} else {
|
||||
unsafe extern "C" fn EVP_PKEY_up_ref(pkey: *mut ffi::EVP_PKEY) {
|
||||
ffi::CRYPTO_add_lock(
|
||||
&mut (*pkey).references,
|
||||
1,
|
||||
ffi::CRYPTO_LOCK_EVP_PKEY,
|
||||
"pkey.rs\0".as_ptr() as *const _,
|
||||
line!() as c_int,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
|
||||
let mut pad: c_int = 0;
|
||||
unsafe {
|
||||
cvt(
|
||||
ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad),
|
||||
)?;
|
||||
};
|
||||
Ok(Padding::from_raw(pad))
|
||||
}
|
||||
|
||||
pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn derive_set_peer(&mut self, peer: &PKeyRef) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(
|
||||
ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), peer.as_ptr()),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn derive(&mut self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mut len: size_t = 0;
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_derive(
|
||||
self.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
&mut len,
|
||||
))?;
|
||||
}
|
||||
|
||||
let mut key = vec![0u8; len];
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_derive(
|
||||
self.as_ptr(),
|
||||
key.as_mut_ptr(),
|
||||
&mut len,
|
||||
))?;
|
||||
}
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use symm::Cipher;
|
||||
use dh::Dh;
|
||||
use dsa::Dsa;
|
||||
use ec::{EcGroup, EcKey};
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
use rsa::Rsa;
|
||||
use nid;
|
||||
use symm::Cipher;
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -314,7 +632,8 @@ mod tests {
|
||||
fn test_to_password() {
|
||||
let rsa = Rsa::generate(2048).unwrap();
|
||||
let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
let pem = pkey.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
|
||||
let pem = pkey
|
||||
.private_key_to_pem_pkcs8_passphrase(Cipher::aes_128_cbc(), b"foobar")
|
||||
.unwrap();
|
||||
PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
|
||||
assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
||||
@ -334,7 +653,8 @@ mod tests {
|
||||
password_queried = true;
|
||||
password[..6].copy_from_slice(b"mypass");
|
||||
Ok(6)
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
assert!(password_queried);
|
||||
}
|
||||
|
||||
@ -367,7 +687,7 @@ mod tests {
|
||||
let key = include_bytes!("../test/key.pem");
|
||||
let key = PKey::private_key_from_pem(key).unwrap();
|
||||
|
||||
let priv_key = key.private_key_to_pem().unwrap();
|
||||
let priv_key = key.private_key_to_pem_pkcs8().unwrap();
|
||||
let pub_key = key.public_key_to_pem().unwrap();
|
||||
|
||||
// As a super-simple verification, just check that the buffers contain
|
||||
@ -381,6 +701,7 @@ mod tests {
|
||||
let rsa = Rsa::generate(2048).unwrap();
|
||||
let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
pkey.rsa().unwrap();
|
||||
assert_eq!(pkey.id(), Id::RSA);
|
||||
assert!(pkey.dsa().is_err());
|
||||
}
|
||||
|
||||
@ -389,37 +710,26 @@ mod tests {
|
||||
let dsa = Dsa::generate(2048).unwrap();
|
||||
let pkey = PKey::from_dsa(dsa).unwrap();
|
||||
pkey.dsa().unwrap();
|
||||
assert_eq!(pkey.id(), Id::DSA);
|
||||
assert!(pkey.rsa().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dh_accessor() {
|
||||
let dh = include_bytes!("../test/dhparams.pem");
|
||||
let dh = Dh::from_pem(dh).unwrap();
|
||||
let dh = Dh::params_from_pem(dh).unwrap();
|
||||
let pkey = PKey::from_dh(dh).unwrap();
|
||||
pkey.dh().unwrap();
|
||||
assert_eq!(pkey.id(), Id::DH);
|
||||
assert!(pkey.rsa().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ec_key_accessor() {
|
||||
let ec_key = EcKey::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let ec_key = EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let pkey = PKey::from_ec_key(ec_key).unwrap();
|
||||
pkey.ec_key().unwrap();
|
||||
assert_eq!(pkey.id(), Id::EC);
|
||||
assert!(pkey.rsa().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ec_key_derive() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let ec_key = EcKey::generate(&group).unwrap();
|
||||
let ec_key2 = EcKey::generate(&group).unwrap();
|
||||
let pkey = PKey::from_ec_key(ec_key).unwrap();
|
||||
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
|
||||
let mut pkey_ctx = PKeyCtx::from_pkey(&pkey).unwrap();
|
||||
pkey_ctx.derive_init().unwrap();
|
||||
pkey_ctx.derive_set_peer(&pkey2).unwrap();
|
||||
let shared = pkey_ctx.derive().unwrap();
|
||||
assert!(!shared.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,14 +10,16 @@
|
||||
//! let mut buf = [0; 256];
|
||||
//! rand_bytes(&mut buf).unwrap();
|
||||
//! ```
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
|
||||
use cvt;
|
||||
use error::ErrorStack;
|
||||
|
||||
/// Fill buffer with cryptographically strong pseudo-random bytes.
|
||||
///
|
||||
/// This corresponds to [`RAND_bytes`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// To generate a buffer with cryptographically strong bytes:
|
||||
@ -29,9 +31,7 @@ use error::ErrorStack;
|
||||
/// rand_bytes(&mut buf).unwrap();
|
||||
/// ```
|
||||
///
|
||||
/// # External OpenSSL Documentation
|
||||
///
|
||||
/// [RAND_bytes](https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html)
|
||||
/// [`RAND_bytes`]: https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html
|
||||
pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
@ -40,6 +40,20 @@ pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Controls random device file descriptor behavior.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`RAND_keep_random_devices_open`].
|
||||
///
|
||||
/// [`RAND_keep_random_devices_open`]: https://www.openssl.org/docs/manmaster/man3/RAND_keep_random_devices_open.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn keep_random_devices_open(keep: bool) {
|
||||
unsafe {
|
||||
ffi::RAND_keep_random_devices_open(keep as c_int);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::rand_bytes;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -16,18 +16,17 @@
|
||||
//! ```rust
|
||||
//! extern crate openssl;
|
||||
//! extern crate hex;
|
||||
//!
|
||||
//!
|
||||
//! use openssl::sha;
|
||||
//! use hex::ToHex;
|
||||
//!
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let mut hasher = sha::Sha256::new();
|
||||
//!
|
||||
//!
|
||||
//! hasher.update(b"Hello, ");
|
||||
//! hasher.update(b"world");
|
||||
//!
|
||||
//!
|
||||
//! let hash = hasher.finish();
|
||||
//! println!("Hashed \"Hello, world\" to {}", hash.to_hex());
|
||||
//! println!("Hashed \"Hello, world\" to {}", hex::encode(hash));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
@ -40,15 +39,14 @@
|
||||
//! extern crate hex;
|
||||
//!
|
||||
//! use openssl::sha::sha256;
|
||||
//! use hex::ToHex;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let hash = sha256(b"your data or message");
|
||||
//! println!("Hash = {}", hash.to_hex());
|
||||
//! println!("Hash = {}", hex::encode(hash));
|
||||
//! }
|
||||
//! ```
|
||||
use libc::c_void;
|
||||
use ffi;
|
||||
use libc::c_void;
|
||||
use std::mem;
|
||||
|
||||
/// Computes the SHA1 hash of some data.
|
||||
@ -288,7 +286,7 @@ impl Sha512 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hex::ToHex;
|
||||
use hex;
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -297,7 +295,7 @@ mod test {
|
||||
let data = b"abc";
|
||||
let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
|
||||
|
||||
assert_eq!(sha1(data).to_hex(), expected);
|
||||
assert_eq!(hex::encode(sha1(data)), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -307,7 +305,7 @@ mod test {
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(b"a");
|
||||
hasher.update(b"bc");
|
||||
assert_eq!(hasher.finish().to_hex(), expected);
|
||||
assert_eq!(hex::encode(hasher.finish()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -315,7 +313,7 @@ mod test {
|
||||
let data = b"abc";
|
||||
let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
|
||||
|
||||
assert_eq!(sha224(data).to_hex(), expected);
|
||||
assert_eq!(hex::encode(sha224(data)), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -325,7 +323,7 @@ mod test {
|
||||
let mut hasher = Sha224::new();
|
||||
hasher.update(b"a");
|
||||
hasher.update(b"bc");
|
||||
assert_eq!(hasher.finish().to_hex(), expected);
|
||||
assert_eq!(hex::encode(hasher.finish()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -333,7 +331,7 @@ mod test {
|
||||
let data = b"abc";
|
||||
let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
|
||||
|
||||
assert_eq!(sha256(data).to_hex(), expected);
|
||||
assert_eq!(hex::encode(sha256(data)), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -343,46 +341,50 @@ mod test {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"a");
|
||||
hasher.update(b"bc");
|
||||
assert_eq!(hasher.finish().to_hex(), expected);
|
||||
assert_eq!(hex::encode(hasher.finish()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_384() {
|
||||
let data = b"abc";
|
||||
let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
|
||||
7cc2358baeca134c825a7";
|
||||
let expected =
|
||||
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
|
||||
7cc2358baeca134c825a7";
|
||||
|
||||
assert_eq!((&sha384(data)[..]).to_hex(), expected);
|
||||
assert_eq!(hex::encode(&sha384(data)[..]), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_384() {
|
||||
let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
|
||||
7cc2358baeca134c825a7";
|
||||
let expected =
|
||||
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
|
||||
7cc2358baeca134c825a7";
|
||||
|
||||
let mut hasher = Sha384::new();
|
||||
hasher.update(b"a");
|
||||
hasher.update(b"bc");
|
||||
assert_eq!((&hasher.finish()[..]).to_hex(), expected);
|
||||
assert_eq!(hex::encode(&hasher.finish()[..]), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_512() {
|
||||
let data = b"abc";
|
||||
let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
|
||||
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||
let expected =
|
||||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
|
||||
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||
|
||||
assert_eq!((&sha512(data)[..]).to_hex(), expected);
|
||||
assert_eq!(hex::encode(&sha512(data)[..]), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_512() {
|
||||
let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
|
||||
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||
let expected =
|
||||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
|
||||
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(b"a");
|
||||
hasher.update(b"bc");
|
||||
assert_eq!((&hasher.finish()[..]).to_hex(), expected);
|
||||
assert_eq!(hex::encode(&hasher.finish()[..]), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
|
||||
//! signer.update(data).unwrap();
|
||||
//! signer.update(data2).unwrap();
|
||||
//! let signature = signer.finish().unwrap();
|
||||
//! let signature = signer.sign_to_vec().unwrap();
|
||||
//!
|
||||
//! // Verify the data
|
||||
//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
|
||||
@ -63,27 +63,57 @@
|
||||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::c_int;
|
||||
use std::io::{self, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use hash::MessageDigest;
|
||||
use pkey::{PKeyCtxRef, PKeyRef};
|
||||
use error::ErrorStack;
|
||||
use hash::MessageDigest;
|
||||
use pkey::{HasPrivate, HasPublic, PKeyRef};
|
||||
use rsa::Padding;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
} else {
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
}
|
||||
}
|
||||
|
||||
/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
|
||||
pub struct RsaPssSaltlen(c_int);
|
||||
|
||||
impl RsaPssSaltlen {
|
||||
/// Returns the integer representation of `RsaPssSaltlen`.
|
||||
fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Sets the salt length to the given value.
|
||||
pub fn custom(val: c_int) -> RsaPssSaltlen {
|
||||
RsaPssSaltlen(val)
|
||||
}
|
||||
|
||||
/// The salt length is set to the digest length.
|
||||
/// Corresponds to the special value `-1`.
|
||||
pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
|
||||
/// The salt length is set to the maximum permissible value.
|
||||
/// Corresponds to the special value `-2`.
|
||||
pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
|
||||
}
|
||||
|
||||
/// A type which computes cryptographic signatures of data.
|
||||
pub struct Signer<'a> {
|
||||
md_ctx: *mut ffi::EVP_MD_CTX,
|
||||
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
|
||||
pkey_pd: PhantomData<&'a PKeyRef>,
|
||||
pctx: *mut ffi::EVP_PKEY_CTX,
|
||||
_p: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Sync for Signer<'a> {}
|
||||
unsafe impl<'a> Send for Signer<'a> {}
|
||||
|
||||
impl<'a> Drop for Signer<'a> {
|
||||
fn drop(&mut self) {
|
||||
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
|
||||
@ -96,10 +126,41 @@ impl<'a> Drop for Signer<'a> {
|
||||
impl<'a> Signer<'a> {
|
||||
/// Creates a new `Signer`.
|
||||
///
|
||||
/// This cannot be used with Ed25519 or Ed448 keys. Please refer to
|
||||
/// `new_without_digest`.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestSignInit`].
|
||||
///
|
||||
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
|
||||
pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Signer<'a>, ErrorStack> {
|
||||
pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
Self::new_intern(Some(type_), pkey)
|
||||
}
|
||||
|
||||
/// Creates a new `Signer` without a digest.
|
||||
///
|
||||
/// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
|
||||
/// It can also be used to create a CMAC.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestSignInit`].
|
||||
///
|
||||
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
|
||||
pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
Self::new_intern(None, pkey)
|
||||
}
|
||||
|
||||
pub fn new_intern<T>(
|
||||
type_: Option<MessageDigest>,
|
||||
pkey: &'a PKeyRef<T>,
|
||||
) -> Result<Signer<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
|
||||
@ -108,7 +169,7 @@ impl<'a> Signer<'a> {
|
||||
let r = ffi::EVP_DigestSignInit(
|
||||
ctx,
|
||||
&mut pctx,
|
||||
type_.as_ptr(),
|
||||
type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
|
||||
ptr::null_mut(),
|
||||
pkey.as_ptr(),
|
||||
);
|
||||
@ -121,24 +182,81 @@ impl<'a> Signer<'a> {
|
||||
|
||||
Ok(Signer {
|
||||
md_ctx: ctx,
|
||||
pkey_ctx: pctx,
|
||||
pkey_pd: PhantomData,
|
||||
pctx,
|
||||
_p: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the `PKeyCtx` associated with the `Signer`.
|
||||
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
|
||||
/// Returns the RSA padding mode in use.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
|
||||
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
|
||||
unsafe {
|
||||
let mut pad = 0;
|
||||
cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
|
||||
.map(|_| Padding::from_raw(pad))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the `PKeyCtx` associated with the `Signer`.
|
||||
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
|
||||
/// Sets the RSA padding mode.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
|
||||
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
|
||||
self.pctx,
|
||||
padding.as_raw(),
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the RSA PSS salt length.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
|
||||
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
|
||||
self.pctx,
|
||||
len.as_raw(),
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the RSA MGF1 algorithm.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
|
||||
pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
|
||||
self.pctx,
|
||||
md.as_ptr() as *mut _,
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Feeds more data into the `Signer`.
|
||||
///
|
||||
/// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
|
||||
/// Use `sign_oneshot` instead.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestUpdate`].
|
||||
///
|
||||
/// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
|
||||
@ -148,7 +266,8 @@ impl<'a> Signer<'a> {
|
||||
self.md_ctx,
|
||||
buf.as_ptr() as *const _,
|
||||
buf.len(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +280,11 @@ impl<'a> Signer<'a> {
|
||||
///
|
||||
/// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
|
||||
pub fn len(&self) -> Result<usize, ErrorStack> {
|
||||
self.len_intern()
|
||||
}
|
||||
|
||||
#[cfg(not(ossl111))]
|
||||
fn len_intern(&self) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
cvt(ffi::EVP_DigestSignFinal(
|
||||
@ -172,6 +296,21 @@ impl<'a> Signer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
fn len_intern(&self) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
cvt(ffi::EVP_DigestSign(
|
||||
self.md_ctx,
|
||||
ptr::null_mut(),
|
||||
&mut len,
|
||||
ptr::null(),
|
||||
0
|
||||
))?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the signature into the provided buffer, returning the number of bytes written.
|
||||
///
|
||||
/// This method will fail if the buffer is not large enough for the signature. Use the `len`
|
||||
@ -203,9 +342,42 @@ impl<'a> Signer<'a> {
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23", note = "renamed to sign_to_vec")]
|
||||
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
self.sign_to_vec()
|
||||
/// Signs the data in data_buf and writes the siganture into the buffer sig_buf, returning the
|
||||
/// number of bytes written.
|
||||
///
|
||||
/// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data.
|
||||
///
|
||||
/// This method will fail if the buffer is not large enough for the signature. Use the `len`
|
||||
/// method to get an upper bound on the required size.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestSign`].
|
||||
///
|
||||
/// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn sign_oneshot(&self, sig_buf: &mut [u8], data_buf: &[u8]) -> Result<usize, ErrorStack> {
|
||||
unsafe {
|
||||
let mut sig_len = sig_buf.len();
|
||||
cvt(ffi::EVP_DigestSign(
|
||||
self.md_ctx,
|
||||
sig_buf.as_mut_ptr() as *mut _,
|
||||
&mut sig_len,
|
||||
data_buf.as_ptr() as *const _,
|
||||
data_buf.len()
|
||||
))?;
|
||||
Ok(sig_len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the signature.
|
||||
///
|
||||
/// This is a simple convenience wrapper over `len` and `sign_oneshot`.
|
||||
#[cfg(ossl111)]
|
||||
pub fn sign_oneshot_to_vec(&self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mut sig_buf = vec![0; self.len()?];
|
||||
let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
|
||||
// The advertised length is not always equal to the real length for things like DSA
|
||||
sig_buf.truncate(len);
|
||||
Ok(sig_buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,10 +394,13 @@ impl<'a> Write for Signer<'a> {
|
||||
|
||||
pub struct Verifier<'a> {
|
||||
md_ctx: *mut ffi::EVP_MD_CTX,
|
||||
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
|
||||
pkey_pd: PhantomData<&'a PKeyRef>,
|
||||
pctx: *mut ffi::EVP_PKEY_CTX,
|
||||
pkey_pd: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Sync for Verifier<'a> {}
|
||||
unsafe impl<'a> Send for Verifier<'a> {}
|
||||
|
||||
impl<'a> Drop for Verifier<'a> {
|
||||
fn drop(&mut self) {
|
||||
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
|
||||
@ -239,10 +414,38 @@ impl<'a> Drop for Verifier<'a> {
|
||||
impl<'a> Verifier<'a> {
|
||||
/// Creates a new `Verifier`.
|
||||
///
|
||||
/// This cannot be used with Ed25519 or Ed448 keys. Please refer to
|
||||
/// `new_without_digest`.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestVerifyInit`].
|
||||
///
|
||||
/// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
|
||||
pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Verifier<'a>, ErrorStack> {
|
||||
pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
Verifier::new_intern(Some(type_), pkey)
|
||||
}
|
||||
|
||||
/// Creates a new `Verifier` without a digest.
|
||||
///
|
||||
/// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestVerifyInit`].
|
||||
///
|
||||
/// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
|
||||
pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPublic
|
||||
{
|
||||
Verifier::new_intern(None, pkey)
|
||||
}
|
||||
|
||||
|
||||
fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
|
||||
where
|
||||
T: HasPublic,
|
||||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
|
||||
@ -251,7 +454,7 @@ impl<'a> Verifier<'a> {
|
||||
let r = ffi::EVP_DigestVerifyInit(
|
||||
ctx,
|
||||
&mut pctx,
|
||||
type_.as_ptr(),
|
||||
type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
|
||||
ptr::null_mut(),
|
||||
pkey.as_ptr(),
|
||||
);
|
||||
@ -264,24 +467,81 @@ impl<'a> Verifier<'a> {
|
||||
|
||||
Ok(Verifier {
|
||||
md_ctx: ctx,
|
||||
pkey_ctx: pctx,
|
||||
pctx,
|
||||
pkey_pd: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the `PKeyCtx` associated with the `Verifier`.
|
||||
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
|
||||
/// Returns the RSA padding mode in use.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
|
||||
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
|
||||
unsafe {
|
||||
let mut pad = 0;
|
||||
cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
|
||||
.map(|_| Padding::from_raw(pad))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the `PKeyCtx` associated with the `Verifier`.
|
||||
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
|
||||
/// Sets the RSA padding mode.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
|
||||
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
|
||||
self.pctx,
|
||||
padding.as_raw(),
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the RSA PSS salt length.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
|
||||
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
|
||||
self.pctx,
|
||||
len.as_raw(),
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the RSA MGF1 algorithm.
|
||||
///
|
||||
/// This is only useful for RSA keys.
|
||||
///
|
||||
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
|
||||
///
|
||||
/// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
|
||||
pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
|
||||
self.pctx,
|
||||
md.as_ptr() as *mut _,
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Feeds more data into the `Verifier`.
|
||||
///
|
||||
/// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
|
||||
/// Use `verify_oneshot` instead.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestUpdate`].
|
||||
///
|
||||
/// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
|
||||
@ -291,7 +551,8 @@ impl<'a> Verifier<'a> {
|
||||
self.md_ctx,
|
||||
buf.as_ptr() as *const _,
|
||||
buf.len(),
|
||||
)).map(|_| ())
|
||||
))
|
||||
.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +564,7 @@ impl<'a> Verifier<'a> {
|
||||
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let r =
|
||||
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
|
||||
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
|
||||
match r {
|
||||
1 => Ok(true),
|
||||
0 => {
|
||||
@ -315,9 +576,30 @@ impl<'a> Verifier<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23", note = "renamed to `verify`")]
|
||||
pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
|
||||
self.verify(signature)
|
||||
/// Determines if the data given in buf matches the provided signature.
|
||||
///
|
||||
/// OpenSSL documentation at [`EVP_DigestVerify`].
|
||||
///
|
||||
/// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn verify_oneshot(&self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let r = ffi::EVP_DigestVerify(
|
||||
self.md_ctx,
|
||||
signature.as_ptr() as *const _,
|
||||
signature.len(),
|
||||
buf.as_ptr() as *const _,
|
||||
buf.len(),
|
||||
);
|
||||
match r {
|
||||
1 => Ok(true),
|
||||
0 => {
|
||||
ErrorStack::get();
|
||||
Ok(false)
|
||||
},
|
||||
_ => Err(ErrorStack::get()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,16 +629,15 @@ unsafe fn EVP_DigestVerifyFinal(
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use hex::{FromHex, ToHex};
|
||||
use hex::{self, FromHex};
|
||||
use std::iter;
|
||||
|
||||
use hash::MessageDigest;
|
||||
use sign::{Signer, Verifier};
|
||||
use ec::{EcGroup, EcKey};
|
||||
use nid;
|
||||
use rsa::{PKCS1_PADDING, Rsa};
|
||||
use dsa::Dsa;
|
||||
use hash::MessageDigest;
|
||||
use nid::Nid;
|
||||
use pkey::PKey;
|
||||
use rsa::{Padding, Rsa};
|
||||
use sign::{RsaPssSaltlen, Signer, Verifier};
|
||||
|
||||
const INPUT: &'static str =
|
||||
"65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
|
||||
@ -378,15 +659,12 @@ mod test {
|
||||
let pkey = PKey::from_rsa(private_key).unwrap();
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
|
||||
signer
|
||||
.pkey_ctx_mut()
|
||||
.set_rsa_padding(PKCS1_PADDING)
|
||||
.unwrap();
|
||||
assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
|
||||
signer.set_rsa_padding(Padding::PKCS1).unwrap();
|
||||
signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
|
||||
let result = signer.sign_to_vec().unwrap();
|
||||
|
||||
assert_eq!(result.to_hex(), SIGNATURE);
|
||||
assert_eq!(hex::encode(result), SIGNATURE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -396,10 +674,7 @@ mod test {
|
||||
let pkey = PKey::from_rsa(private_key).unwrap();
|
||||
|
||||
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
assert_eq!(
|
||||
verifier.pkey_ctx_mut().rsa_padding().unwrap(),
|
||||
PKCS1_PADDING
|
||||
);
|
||||
assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
|
||||
verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
|
||||
assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
|
||||
}
|
||||
@ -416,56 +691,6 @@ mod test {
|
||||
assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn dsa_sign_verify() {
|
||||
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
|
||||
|
||||
let private_key = {
|
||||
let key = include_bytes!("../test/dsa.pem");
|
||||
PKey::from_dsa(Dsa::private_key_from_pem(key).unwrap()).unwrap()
|
||||
};
|
||||
|
||||
let public_key = {
|
||||
let key = include_bytes!("../test/dsa.pem.pub");
|
||||
PKey::from_dsa(Dsa::public_key_from_pem(key).unwrap()).unwrap()
|
||||
};
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
|
||||
signer.update(&input).unwrap();
|
||||
let sig = signer.sign_to_vec().unwrap();
|
||||
|
||||
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
|
||||
verifier.update(&input).unwrap();
|
||||
assert!(verifier.verify(&sig).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn dsa_sign_verify_fail() {
|
||||
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
|
||||
|
||||
let private_key = {
|
||||
let key = include_bytes!("../test/dsa.pem");
|
||||
PKey::from_dsa(Dsa::private_key_from_pem(key).unwrap()).unwrap()
|
||||
};
|
||||
|
||||
let public_key = {
|
||||
let key = include_bytes!("../test/dsa.pem.pub");
|
||||
PKey::from_dsa(Dsa::public_key_from_pem(key).unwrap()).unwrap()
|
||||
};
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
|
||||
signer.update(&input).unwrap();
|
||||
let mut sig = signer.sign_to_vec().unwrap();
|
||||
sig[0] -= 1;
|
||||
|
||||
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
|
||||
verifier.update(&input).unwrap();
|
||||
match verifier.verify(&sig) {
|
||||
Ok(true) => panic!("unexpected success"),
|
||||
Ok(false) | Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
|
||||
for &(ref key, ref data, ref res) in tests.iter() {
|
||||
let pkey = PKey::hmac(key).unwrap();
|
||||
@ -567,9 +792,26 @@ mod test {
|
||||
test_hmac(MessageDigest::sha1(), &tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(ossl110)]
|
||||
fn test_cmac() {
|
||||
let cipher = ::symm::Cipher::aes_128_cbc();
|
||||
let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap();
|
||||
let pkey = PKey::cmac(&cipher, &key).unwrap();
|
||||
let mut signer = Signer::new_without_digest(&pkey).unwrap();
|
||||
|
||||
let data = b"Hi There";
|
||||
signer.update(data as &[u8]).unwrap();
|
||||
|
||||
let expected = vec![
|
||||
136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
|
||||
];
|
||||
assert_eq!(signer.sign_to_vec().unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ec() {
|
||||
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
let key = PKey::from_ec_key(key).unwrap();
|
||||
|
||||
@ -581,4 +823,43 @@ mod test {
|
||||
verifier.update(b"hello world").unwrap();
|
||||
assert!(verifier.verify(&signature).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(ossl111)]
|
||||
fn eddsa() {
|
||||
let key = PKey::generate_ed25519().unwrap();
|
||||
|
||||
let signer = Signer::new_without_digest(&key).unwrap();
|
||||
let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap();
|
||||
|
||||
let verifier = Verifier::new_without_digest(&key).unwrap();
|
||||
assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(ossl111)]
|
||||
fn rsa_sign_verify() {
|
||||
let key = include_bytes!("../test/rsa.pem");
|
||||
let private_key = Rsa::private_key_from_pem(key).unwrap();
|
||||
let pkey = PKey::from_rsa(private_key).unwrap();
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
|
||||
assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
|
||||
signer
|
||||
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
|
||||
.unwrap();
|
||||
signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
|
||||
signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
|
||||
let signature = signer.sign_to_vec().unwrap();
|
||||
|
||||
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
|
||||
verifier
|
||||
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
|
||||
.unwrap();
|
||||
verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
|
||||
verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
|
||||
assert!(verifier.verify(&signature).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
57
openssl/src/srtp.rs
Normal file
57
openssl/src/srtp.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::c_ulong;
|
||||
use stack::Stackable;
|
||||
use std::ffi::CStr;
|
||||
use std::str;
|
||||
|
||||
/// fake free method, since SRTP_PROTECTION_PROFILE is static
|
||||
unsafe fn free(_profile: *mut ffi::SRTP_PROTECTION_PROFILE) {}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::SRTP_PROTECTION_PROFILE;
|
||||
fn drop = free;
|
||||
|
||||
pub struct SrtpProtectionProfile;
|
||||
/// Reference to `SrtpProtectionProfile`.
|
||||
pub struct SrtpProtectionProfileRef;
|
||||
}
|
||||
|
||||
impl Stackable for SrtpProtectionProfile {
|
||||
type StackType = ffi::stack_st_SRTP_PROTECTION_PROFILE;
|
||||
}
|
||||
|
||||
impl SrtpProtectionProfileRef {
|
||||
pub fn id(&self) -> SrtpProfileId {
|
||||
SrtpProfileId::from_raw(unsafe { (*self.as_ptr()).id })
|
||||
}
|
||||
pub fn name(&self) -> &'static str {
|
||||
unsafe { CStr::from_ptr((*self.as_ptr()).name as *const _) }
|
||||
.to_str()
|
||||
.expect("should be UTF-8")
|
||||
}
|
||||
}
|
||||
|
||||
/// An identifier of an SRTP protection profile.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SrtpProfileId(c_ulong);
|
||||
|
||||
impl SrtpProfileId {
|
||||
/// Creates a `SrtpProfileId` from an integer representation.
|
||||
pub fn from_raw(value: c_ulong) -> SrtpProfileId {
|
||||
SrtpProfileId(value)
|
||||
}
|
||||
|
||||
/// Returns the integer representation of `SrtpProfileId`.
|
||||
pub fn as_raw(&self) -> c_ulong {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub const SRTP_AES128_CM_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_80);
|
||||
pub const SRTP_AES128_CM_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_32);
|
||||
pub const SRTP_AES128_F8_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_80);
|
||||
pub const SRTP_AES128_F8_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32);
|
||||
pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80);
|
||||
pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32);
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
use ffi::{
|
||||
self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO,
|
||||
BIO_CTRL_FLUSH,
|
||||
};
|
||||
use libc::{c_char, c_int, c_long, c_void, strlen};
|
||||
use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags, BIO_set_retry_read,
|
||||
BIO_set_retry_write};
|
||||
use std::any::Any;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
@ -15,15 +17,15 @@ use error::ErrorStack;
|
||||
pub struct StreamState<S> {
|
||||
pub stream: S,
|
||||
pub error: Option<io::Error>,
|
||||
pub panic: Option<Box<Any + Send>>,
|
||||
pub panic: Option<Box<dyn Any + Send>>,
|
||||
}
|
||||
|
||||
/// Safe wrapper for BIO_METHOD
|
||||
pub struct BioMethod(compat::BIO_METHOD);
|
||||
pub struct BioMethod(BIO_METHOD);
|
||||
|
||||
impl BioMethod {
|
||||
fn new<S: Read + Write>() -> BioMethod {
|
||||
BioMethod(compat::BIO_METHOD::new::<S>())
|
||||
BioMethod(BIO_METHOD::new::<S>())
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +43,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta
|
||||
|
||||
unsafe {
|
||||
let bio = cvt_p(BIO_new(method.0.get()))?;
|
||||
compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
|
||||
compat::BIO_set_init(bio, 1);
|
||||
BIO_set_data(bio, Box::into_raw(state) as *mut _);
|
||||
BIO_set_init(bio, 1);
|
||||
|
||||
return Ok((bio, method));
|
||||
}
|
||||
@ -53,13 +55,13 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
|
||||
state.error.take()
|
||||
}
|
||||
|
||||
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
|
||||
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<dyn Any + Send>> {
|
||||
let state = state::<S>(bio);
|
||||
state.panic.take()
|
||||
}
|
||||
|
||||
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
|
||||
let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
|
||||
let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio));
|
||||
&state.stream
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
|
||||
}
|
||||
|
||||
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
|
||||
&mut *(compat::BIO_get_data(bio) as *mut _)
|
||||
&mut *(BIO_get_data(bio) as *mut _)
|
||||
}
|
||||
|
||||
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
|
||||
@ -117,8 +119,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
|
||||
|
||||
fn retriable_error(err: &io::Error) -> bool {
|
||||
match err.kind() {
|
||||
io::ErrorKind::WouldBlock |
|
||||
io::ErrorKind::NotConnected => true,
|
||||
io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -153,10 +154,10 @@ unsafe extern "C" fn ctrl<S: Write>(
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
|
||||
compat::BIO_set_init(bio, 0);
|
||||
compat::BIO_set_num(bio, 0);
|
||||
compat::BIO_set_data(bio, ptr::null_mut());
|
||||
compat::BIO_set_flags(bio, 0);
|
||||
BIO_set_init(bio, 0);
|
||||
BIO_set_num(bio, 0);
|
||||
BIO_set_data(bio, ptr::null_mut());
|
||||
BIO_set_flags(bio, 0);
|
||||
1
|
||||
}
|
||||
|
||||
@ -165,115 +166,110 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let data = compat::BIO_get_data(bio);
|
||||
let data = BIO_get_data(bio);
|
||||
assert!(!data.is_null());
|
||||
Box::<StreamState<S>>::from_raw(data as *mut _);
|
||||
compat::BIO_set_data(bio, ptr::null_mut());
|
||||
compat::BIO_set_init(bio, 0);
|
||||
BIO_set_data(bio, ptr::null_mut());
|
||||
BIO_set_init(bio, 0);
|
||||
1
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use std::io::{Read, Write};
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl273))] {
|
||||
use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
|
||||
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
||||
|
||||
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
||||
#[allow(bad_style)]
|
||||
struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
|
||||
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
impl BIO_METHOD {
|
||||
fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
unsafe {
|
||||
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
|
||||
assert!(!ptr.is_null());
|
||||
let ret = BIO_METHOD(ptr);
|
||||
assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_create(ptr, create) != 0);
|
||||
assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
impl BIO_METHOD {
|
||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
unsafe {
|
||||
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
|
||||
assert!(!ptr.is_null());
|
||||
let ret = BIO_METHOD(ptr);
|
||||
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
|
||||
assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
|
||||
return ret;
|
||||
fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BIO_METHOD {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::BIO_meth_free(self.0);
|
||||
impl Drop for BIO_METHOD {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::BIO_meth_free(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
|
||||
impl BIO_METHOD {
|
||||
fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
let ptr = Box::new(ffi::BIO_METHOD {
|
||||
type_: ffi::BIO_TYPE_NONE,
|
||||
name: b"rust\0".as_ptr() as *const _,
|
||||
bwrite: Some(bwrite::<S>),
|
||||
bread: Some(bread::<S>),
|
||||
bputs: Some(bputs::<S>),
|
||||
bgets: None,
|
||||
ctrl: Some(ctrl::<S>),
|
||||
create: Some(create),
|
||||
destroy: Some(destroy::<S>),
|
||||
callback_ctrl: None,
|
||||
});
|
||||
|
||||
BIO_METHOD(Box::into_raw(ptr))
|
||||
}
|
||||
|
||||
fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BIO_METHOD {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
Box::<ffi::BIO_METHOD>::from_raw(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
|
||||
(*bio).init = init;
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
|
||||
(*bio).flags = flags;
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
|
||||
(*bio).ptr
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
|
||||
(*bio).ptr = data;
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
|
||||
(*bio).num = num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use ffi;
|
||||
use libc::{c_int, c_void};
|
||||
|
||||
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
|
||||
impl BIO_METHOD {
|
||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
let ptr = Box::new(ffi::BIO_METHOD {
|
||||
type_: ffi::BIO_TYPE_NONE,
|
||||
name: b"rust\0".as_ptr() as *const _,
|
||||
bwrite: Some(super::bwrite::<S>),
|
||||
bread: Some(super::bread::<S>),
|
||||
bputs: Some(super::bputs::<S>),
|
||||
bgets: None,
|
||||
ctrl: Some(super::ctrl::<S>),
|
||||
create: Some(super::create),
|
||||
destroy: Some(super::destroy::<S>),
|
||||
callback_ctrl: None,
|
||||
});
|
||||
|
||||
BIO_METHOD(Box::into_raw(ptr))
|
||||
}
|
||||
|
||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BIO_METHOD {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
Box::<ffi::BIO_METHOD>::from_raw(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
|
||||
(*bio).init = init;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
|
||||
(*bio).flags = flags;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
|
||||
(*bio).ptr
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
|
||||
(*bio).ptr = data;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
|
||||
(*bio).num = num;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,40 +1,58 @@
|
||||
use ffi;
|
||||
use libc::{c_int, c_uint, c_char, c_uchar, c_void};
|
||||
use std::any::Any;
|
||||
use foreign_types::ForeignType;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))]
|
||||
use libc::c_char;
|
||||
#[cfg(ossl111)]
|
||||
use libc::size_t;
|
||||
use libc::{c_int, c_uchar, c_uint, c_void};
|
||||
#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))]
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::mem;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
#[cfg(ossl111)]
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
use error::ErrorStack;
|
||||
use dh::Dh;
|
||||
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
|
||||
use ec_key::EcKey;
|
||||
use ssl::{get_callback_idx, get_ssl_callback_idx, SslRef, SniError, NPN_PROTOS_IDX};
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
use ssl::ALPN_PROTOS_IDX;
|
||||
use x509::X509StoreContextRef;
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
use ec::EcKey;
|
||||
use error::ErrorStack;
|
||||
use pkey::Params;
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
use ssl::AlpnError;
|
||||
#[cfg(ossl111)]
|
||||
use ssl::{ClientHelloResponse, ExtensionContext};
|
||||
use ssl::{SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, SslSession, SslSessionRef, SESSION_CTX_INDEX};
|
||||
#[cfg(ossl111)]
|
||||
use x509::X509Ref;
|
||||
use x509::{X509StoreContext, X509StoreContextRef};
|
||||
|
||||
pub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
|
||||
where
|
||||
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
|
||||
F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
||||
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
|
||||
let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
|
||||
let verify: &F = &*(verify as *mut F);
|
||||
let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx);
|
||||
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
|
||||
let verify_idx = SslContext::cached_ex_index::<F>();
|
||||
|
||||
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
|
||||
// raw pointer shenanigans to break the borrow of ctx
|
||||
// the callback can't mess with its own ex_data slot so this is safe
|
||||
let verify = ctx
|
||||
.ex_data(ssl_idx)
|
||||
.expect("BUG: store context missing ssl")
|
||||
.ssl_context()
|
||||
.ex_data(verify_idx)
|
||||
.expect("BUG: verify callback missing") as *const F;
|
||||
|
||||
verify(preverify_ok != 0, ctx) as c_int
|
||||
(*verify)(preverify_ok != 0, ctx) as c_int
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
pub extern "C" fn raw_psk<F>(
|
||||
pub extern "C" fn raw_client_psk<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
hint: *const c_char,
|
||||
identity: *mut c_char,
|
||||
@ -44,17 +62,19 @@ pub extern "C" fn raw_psk<F>(
|
||||
) -> c_uint
|
||||
where
|
||||
F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack>
|
||||
+ Any
|
||||
+ 'static
|
||||
+ Sync
|
||||
+ Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
|
||||
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = &*(callback as *mut F);
|
||||
let hint = if hint != ptr::null() {
|
||||
let callback_idx = SslContext::cached_ex_index::<F>();
|
||||
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(callback_idx)
|
||||
.expect("BUG: psk callback missing") as *const F;
|
||||
let hint = if !hint.is_null() {
|
||||
Some(CStr::from_ptr(hint).to_bytes())
|
||||
} else {
|
||||
None
|
||||
@ -62,9 +82,50 @@ where
|
||||
// Give the callback mutable slices into which it can write the identity and psk.
|
||||
let identity_sl = slice::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize);
|
||||
let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize);
|
||||
match callback(ssl, hint, identity_sl, psk_sl) {
|
||||
match (*callback)(ssl, hint, identity_sl, psk_sl) {
|
||||
Ok(psk_len) => psk_len as u32,
|
||||
_ => 0,
|
||||
Err(e) => {
|
||||
e.put();
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
pub extern "C" fn raw_server_psk<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
identity: *const c_char,
|
||||
psk: *mut c_uchar,
|
||||
max_psk_len: c_uint,
|
||||
) -> c_uint
|
||||
where
|
||||
F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8]) -> Result<usize, ErrorStack>
|
||||
+ 'static
|
||||
+ Sync
|
||||
+ Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback_idx = SslContext::cached_ex_index::<F>();
|
||||
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(callback_idx)
|
||||
.expect("BUG: psk callback missing") as *const F;
|
||||
let identity = if identity != ptr::null() {
|
||||
Some(CStr::from_ptr(identity).to_bytes())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
// Give the callback mutable slices into which it can write the psk.
|
||||
let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize);
|
||||
match (*callback)(ssl, identity, psk_sl) {
|
||||
Ok(psk_len) => psk_len as u32,
|
||||
Err(e) => {
|
||||
e.put();
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,100 +135,71 @@ pub extern "C" fn ssl_raw_verify<F>(
|
||||
x509_ctx: *mut ffi::X509_STORE_CTX,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
|
||||
F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
||||
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
|
||||
let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_callback_idx::<F>());
|
||||
let verify: &F = &*(verify as *mut F);
|
||||
let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx);
|
||||
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
|
||||
let callback_idx = Ssl::cached_ex_index::<Arc<F>>();
|
||||
|
||||
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
|
||||
let callback = ctx
|
||||
.ex_data(ssl_idx)
|
||||
.expect("BUG: store context missing ssl")
|
||||
.ex_data(callback_idx)
|
||||
.expect("BUG: ssl verify callback missing")
|
||||
.clone();
|
||||
|
||||
verify(preverify_ok != 0, ctx) as c_int
|
||||
callback(preverify_ok != 0, ctx) as c_int
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int
|
||||
pub extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, arg: *mut c_void) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef, &mut SslAlert) -> Result<(), SniError> + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
|
||||
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
|
||||
let callback: &F = &*(callback as *mut F);
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = arg as *const F;
|
||||
let mut alert = SslAlert(*al);
|
||||
|
||||
match callback(ssl) {
|
||||
let r = (*callback)(ssl, &mut alert);
|
||||
*al = alert.0;
|
||||
match r {
|
||||
Ok(()) => ffi::SSL_TLSEXT_ERR_OK,
|
||||
Err(SniError::Fatal(e)) => {
|
||||
*al = e;
|
||||
ffi::SSL_TLSEXT_ERR_ALERT_FATAL
|
||||
}
|
||||
Err(SniError::Warning(e)) => {
|
||||
*al = e;
|
||||
ffi::SSL_TLSEXT_ERR_ALERT_WARNING
|
||||
}
|
||||
Err(SniError::NoAck) => ffi::SSL_TLSEXT_ERR_NOACK,
|
||||
Err(e) => e.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn select_proto_using(
|
||||
ssl: *mut ffi::SSL,
|
||||
out: *mut *mut c_uchar,
|
||||
outlen: *mut c_uchar,
|
||||
inbuf: *const c_uchar,
|
||||
inlen: c_uint,
|
||||
ex_data: c_int,
|
||||
) -> c_int {
|
||||
|
||||
// First, get the list of protocols (that the client should support) saved in the context
|
||||
// extra data.
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
|
||||
let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, ex_data);
|
||||
let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>);
|
||||
// Prepare the client list parameters to be passed to the OpenSSL function...
|
||||
let client = protocols.as_ptr();
|
||||
let client_len = protocols.len() as c_uint;
|
||||
// Finally, let OpenSSL find a protocol to be used, by matching the given server and
|
||||
// client lists.
|
||||
if ffi::SSL_select_next_proto(out, outlen, inbuf, inlen, client, client_len) !=
|
||||
ffi::OPENSSL_NPN_NEGOTIATED
|
||||
{
|
||||
ffi::SSL_TLSEXT_ERR_NOACK
|
||||
} else {
|
||||
ffi::SSL_TLSEXT_ERR_OK
|
||||
}
|
||||
}
|
||||
|
||||
/// The function is given as the callback to `SSL_CTX_set_next_proto_select_cb`.
|
||||
///
|
||||
/// It chooses the protocol that the client wishes to use, out of the given list of protocols
|
||||
/// supported by the server. It achieves this by delegating to the `SSL_select_next_proto`
|
||||
/// function. The list of protocols supported by the client is found in the extra data of the
|
||||
/// OpenSSL context.
|
||||
pub extern "C" fn raw_next_proto_select_cb(
|
||||
ssl: *mut ffi::SSL,
|
||||
out: *mut *mut c_uchar,
|
||||
outlen: *mut c_uchar,
|
||||
inbuf: *const c_uchar,
|
||||
inlen: c_uint,
|
||||
_arg: *mut c_void,
|
||||
) -> c_int {
|
||||
unsafe { select_proto_using(ssl, out, outlen, inbuf, inlen, *NPN_PROTOS_IDX) }
|
||||
}
|
||||
|
||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||
pub extern "C" fn raw_alpn_select_cb(
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub extern "C" fn raw_alpn_select<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
out: *mut *const c_uchar,
|
||||
outlen: *mut c_uchar,
|
||||
inbuf: *const c_uchar,
|
||||
inlen: c_uint,
|
||||
_arg: *mut c_void,
|
||||
) -> c_int {
|
||||
unsafe { select_proto_using(ssl, out as *mut _, outlen, inbuf, inlen, *ALPN_PROTOS_IDX) }
|
||||
) -> c_int
|
||||
where
|
||||
F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: alpn callback missing") as *const F;
|
||||
let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize);
|
||||
|
||||
match (*callback)(ssl, protos) {
|
||||
Ok(proto) => {
|
||||
*out = proto.as_ptr() as *const c_uchar;
|
||||
*outlen = proto.len() as c_uchar;
|
||||
ffi::SSL_TLSEXT_ERR_OK
|
||||
}
|
||||
Err(e) => e.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn raw_tmp_dh<F>(
|
||||
@ -176,48 +208,50 @@ pub unsafe extern "C" fn raw_tmp_dh<F>(
|
||||
keylength: c_int,
|
||||
) -> *mut ffi::DH
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ctx = ffi::SSL_get_SSL_CTX(ssl);
|
||||
let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
|
||||
let callback = &*(callback as *mut F);
|
||||
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
match callback(ssl, is_export != 0, keylength as u32) {
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: tmp dh callback missing") as *const F;
|
||||
|
||||
match (*callback)(ssl, is_export != 0, keylength as u32) {
|
||||
Ok(dh) => {
|
||||
let ptr = dh.as_ptr();
|
||||
mem::forget(dh);
|
||||
ptr
|
||||
}
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
pub unsafe extern "C" fn raw_tmp_ecdh<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
is_export: c_int,
|
||||
keylength: c_int,
|
||||
) -> *mut ffi::EC_KEY
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ctx = ffi::SSL_get_SSL_CTX(ssl);
|
||||
let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
|
||||
let callback = &*(callback as *mut F);
|
||||
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
match callback(ssl, is_export != 0, keylength as u32) {
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: tmp ecdh callback missing") as *const F;
|
||||
|
||||
match (*callback)(ssl, is_export != 0, keylength as u32) {
|
||||
Ok(ec_key) => {
|
||||
let ptr = ec_key.as_ptr();
|
||||
mem::forget(ec_key);
|
||||
ptr
|
||||
}
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
@ -229,46 +263,50 @@ pub unsafe extern "C" fn raw_tmp_dh_ssl<F>(
|
||||
keylength: c_int,
|
||||
) -> *mut ffi::DH
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>());
|
||||
let callback = &*(callback as *mut F);
|
||||
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
.expect("BUG: ssl tmp dh callback missing")
|
||||
.clone();
|
||||
|
||||
match callback(ssl, is_export != 0, keylength as u32) {
|
||||
Ok(dh) => {
|
||||
let ptr = dh.as_ptr();
|
||||
mem::forget(dh);
|
||||
ptr
|
||||
}
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
is_export: c_int,
|
||||
keylength: c_int,
|
||||
) -> *mut ffi::EC_KEY
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>());
|
||||
let callback = &*(callback as *mut F);
|
||||
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
.expect("BUG: ssl tmp ecdh callback missing")
|
||||
.clone();
|
||||
|
||||
match callback(ssl, is_export != 0, keylength as u32) {
|
||||
Ok(ec_key) => {
|
||||
let ptr = ec_key.as_ptr();
|
||||
mem::forget(ec_key);
|
||||
ptr
|
||||
}
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
@ -276,21 +314,21 @@ where
|
||||
|
||||
pub unsafe extern "C" fn raw_tlsext_status<F>(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + Any + 'static + Sync + Send,
|
||||
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
|
||||
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
|
||||
let callback = &*(callback as *mut F);
|
||||
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let ret = callback(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: ocsp callback missing") as *const F;
|
||||
let ret = (*callback)(ssl);
|
||||
|
||||
if ssl.is_server() {
|
||||
match ret {
|
||||
Ok(true) => ffi::SSL_TLSEXT_ERR_OK,
|
||||
Ok(false) => ffi::SSL_TLSEXT_ERR_NOACK,
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ffi::SSL_TLSEXT_ERR_ALERT_FATAL
|
||||
}
|
||||
}
|
||||
@ -298,42 +336,351 @@ where
|
||||
match ret {
|
||||
Ok(true) => 1,
|
||||
Ok(false) => 0,
|
||||
Err(_) => {
|
||||
// FIXME reset error stack
|
||||
Err(e) => {
|
||||
e.put();
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The function is given as the callback to `SSL_CTX_set_next_protos_advertised_cb`.
|
||||
///
|
||||
/// It causes the parameter `out` to point at a `*const c_uchar` instance that
|
||||
/// represents the list of protocols that the server should advertise as those
|
||||
/// that it supports.
|
||||
/// The list of supported protocols is found in the extra data of the OpenSSL
|
||||
/// context.
|
||||
pub extern "C" fn raw_next_protos_advertise_cb(
|
||||
pub unsafe extern "C" fn raw_new_session<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
out: *mut *const c_uchar,
|
||||
outlen: *mut c_uint,
|
||||
_arg: *mut c_void,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
// First, get the list of (supported) protocols saved in the context extra data.
|
||||
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
|
||||
let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, *NPN_PROTOS_IDX);
|
||||
if protocols.is_null() {
|
||||
*out = b"".as_ptr();
|
||||
*outlen = 0;
|
||||
} else {
|
||||
// If the pointer is valid, put the pointer to the actual byte array into the
|
||||
// output parameter `out`, as well as its length into `outlen`.
|
||||
let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>);
|
||||
*out = protocols.as_ptr();
|
||||
*outlen = protocols.len() as c_uint;
|
||||
session: *mut ffi::SSL_SESSION,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ex_data(*SESSION_CTX_INDEX)
|
||||
.expect("BUG: session context missing")
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: new session callback missing") as *const F;
|
||||
let session = SslSession::from_ptr(session);
|
||||
|
||||
(*callback)(ssl, session);
|
||||
|
||||
// the return code doesn't indicate error vs success, but whether or not we consumed the session
|
||||
1
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn raw_remove_session<F>(
|
||||
ctx: *mut ffi::SSL_CTX,
|
||||
session: *mut ffi::SSL_SESSION,
|
||||
) where
|
||||
F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
|
||||
{
|
||||
let ctx = SslContextRef::from_ptr(ctx);
|
||||
let callback = ctx
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: remove session callback missing");
|
||||
let session = SslSessionRef::from_ptr(session);
|
||||
|
||||
callback(ctx, session)
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
type DataPtr = *const c_uchar;
|
||||
} else {
|
||||
type DataPtr = *mut c_uchar;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn raw_get_session<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
data: DataPtr,
|
||||
len: c_int,
|
||||
copy: *mut c_int,
|
||||
) -> *mut ffi::SSL_SESSION
|
||||
where
|
||||
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ex_data(*SESSION_CTX_INDEX)
|
||||
.expect("BUG: session context missing")
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: get session callback missing") as *const F;
|
||||
let data = slice::from_raw_parts(data as *const u8, len as usize);
|
||||
|
||||
match (*callback)(ssl, data) {
|
||||
Some(session) => {
|
||||
let p = session.as_ptr();
|
||||
mem::forget(session);
|
||||
*copy = 0;
|
||||
p
|
||||
}
|
||||
None => ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub unsafe extern "C" fn raw_keylog<F>(ssl: *const ffi::SSL, line: *const c_char)
|
||||
where
|
||||
F: Fn(&SslRef, &str) + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr(ssl as *mut _);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: get session callback missing");
|
||||
let line = CStr::from_ptr(line).to_bytes();
|
||||
let line = str::from_utf8_unchecked(line);
|
||||
|
||||
callback(ssl, line);
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub unsafe extern "C" fn raw_stateless_cookie_generate<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
cookie: *mut c_uchar,
|
||||
cookie_len: *mut size_t,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: stateless cookie generate callback missing") as *const F;
|
||||
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
|
||||
match (*callback)(ssl, slice) {
|
||||
Ok(len) => {
|
||||
*cookie_len = len as size_t;
|
||||
1
|
||||
}
|
||||
Err(e) => {
|
||||
e.put();
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub unsafe extern "C" fn raw_stateless_cookie_verify<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
cookie: *const c_uchar,
|
||||
cookie_len: size_t,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: stateless cookie verify callback missing") as *const F;
|
||||
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
|
||||
(*callback)(ssl, slice) as c_int
|
||||
}
|
||||
|
||||
pub extern "C" fn raw_cookie_generate<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
cookie: *mut c_uchar,
|
||||
cookie_len: *mut c_uint,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: cookie generate callback missing") as *const F;
|
||||
// We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for
|
||||
// compatibility. See comments in dtls1.h.
|
||||
let slice =
|
||||
slice::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1);
|
||||
match (*callback)(ssl, slice) {
|
||||
Ok(len) => {
|
||||
*cookie_len = len as c_uint;
|
||||
1
|
||||
}
|
||||
Err(e) => {
|
||||
e.put();
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
type CookiePtr = *const c_uchar;
|
||||
} else {
|
||||
type CookiePtr = *mut c_uchar;
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn raw_cookie_verify<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
cookie: CookiePtr,
|
||||
cookie_len: c_uint,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: cookie verify callback missing") as *const F;
|
||||
let slice =
|
||||
slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
|
||||
(*callback)(ssl, slice) as c_int
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub struct CustomExtAddState<T>(Option<T>);
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub extern "C" fn raw_custom_ext_add<F, T>(
|
||||
ssl: *mut ffi::SSL,
|
||||
_: c_uint,
|
||||
context: c_uint,
|
||||
out: *mut *const c_uchar,
|
||||
outlen: *mut size_t,
|
||||
x: *mut ffi::X509,
|
||||
chainidx: size_t,
|
||||
al: *mut c_int,
|
||||
_: *mut c_void,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result<Option<T>, SslAlert>
|
||||
+ 'static
|
||||
+ Sync
|
||||
+ Send,
|
||||
T: AsRef<[u8]> + 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: custom ext add callback missing") as *const F;
|
||||
let ectx = ExtensionContext::from_bits_truncate(context);
|
||||
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
|
||||
Some((chainidx, X509Ref::from_ptr(x)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
match (*callback)(ssl, ectx, cert) {
|
||||
Ok(None) => 0,
|
||||
Ok(Some(buf)) => {
|
||||
*outlen = buf.as_ref().len();
|
||||
*out = buf.as_ref().as_ptr();
|
||||
|
||||
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
|
||||
let mut buf = Some(buf);
|
||||
let new = match ssl.ex_data_mut(idx) {
|
||||
Some(state) => {
|
||||
state.0 = buf.take();
|
||||
false
|
||||
}
|
||||
None => true,
|
||||
};
|
||||
if new {
|
||||
ssl.set_ex_data(idx, CustomExtAddState(buf));
|
||||
}
|
||||
1
|
||||
}
|
||||
Err(alert) => {
|
||||
*al = alert.0;
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub extern "C" fn raw_custom_ext_free<T>(
|
||||
ssl: *mut ffi::SSL,
|
||||
_: c_uint,
|
||||
_: c_uint,
|
||||
_: *mut *const c_uchar,
|
||||
_: *mut c_void,
|
||||
) where
|
||||
T: 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
|
||||
if let Some(state) = ssl.ex_data_mut(idx) {
|
||||
state.0 = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub extern "C" fn raw_custom_ext_parse<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
_: c_uint,
|
||||
context: c_uint,
|
||||
input: *const c_uchar,
|
||||
inlen: size_t,
|
||||
x: *mut ffi::X509,
|
||||
chainidx: size_t,
|
||||
al: *mut c_int,
|
||||
_: *mut c_void,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert>
|
||||
+ 'static
|
||||
+ Sync
|
||||
+ Send,
|
||||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: custom ext parse callback missing") as *const F;
|
||||
let ectx = ExtensionContext::from_bits_truncate(context);
|
||||
let slice = slice::from_raw_parts(input as *const u8, inlen as usize);
|
||||
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
|
||||
Some((chainidx, X509Ref::from_ptr(x)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
match (*callback)(ssl, ectx, slice, cert) {
|
||||
Ok(()) => 1,
|
||||
Err(alert) => {
|
||||
*al = alert.0;
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl111)]
|
||||
pub unsafe extern "C" fn raw_client_hello<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
al: *mut c_int,
|
||||
arg: *mut c_void,
|
||||
) -> c_int
|
||||
where
|
||||
F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack>
|
||||
+ 'static
|
||||
+ Sync
|
||||
+ Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = arg as *const F;
|
||||
let mut alert = SslAlert(*al);
|
||||
|
||||
let r = (*callback)(ssl, &mut alert);
|
||||
*al = alert.0;
|
||||
match r {
|
||||
Ok(c) => c.0,
|
||||
Err(e) => {
|
||||
e.put();
|
||||
ffi::SSL_CLIENT_HELLO_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
ffi::SSL_TLSEXT_ERR_OK
|
||||
}
|
||||
|
||||
@ -3,19 +3,13 @@ use std::ops::{Deref, DerefMut};
|
||||
|
||||
use dh::Dh;
|
||||
use error::ErrorStack;
|
||||
use ssl::{self, HandshakeError, Ssl, SslRef, SslContext, SslContextBuilder, SslMethod, SslStream,
|
||||
SSL_VERIFY_PEER};
|
||||
use pkey::PKeyRef;
|
||||
use ssl::{
|
||||
HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef,
|
||||
SslStream, SslVerifyMode,
|
||||
};
|
||||
use version;
|
||||
use x509::X509Ref;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
lazy_static! {
|
||||
static ref HOSTNAME_IDX: ::ex_data::Index<Ssl, String> = Ssl::new_ex_index().unwrap();
|
||||
}
|
||||
|
||||
// ffdhe2048 from https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe2048
|
||||
const DHPARAM_PEM: &'static str = "
|
||||
const FFDHE_2048: &str = "
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||
@ -29,26 +23,24 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||
fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
|
||||
let mut ctx = SslContextBuilder::new(method)?;
|
||||
|
||||
let mut opts = ssl::SSL_OP_ALL;
|
||||
opts &= !ssl::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
|
||||
opts &= !ssl::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
opts |= ssl::SSL_OP_NO_TICKET;
|
||||
opts |= ssl::SSL_OP_NO_COMPRESSION;
|
||||
opts |= ssl::SSL_OP_NO_SSLV2;
|
||||
opts |= ssl::SSL_OP_NO_SSLV3;
|
||||
opts |= ssl::SSL_OP_SINGLE_DH_USE;
|
||||
opts |= ssl::SSL_OP_SINGLE_ECDH_USE;
|
||||
opts |= ssl::SSL_OP_CIPHER_SERVER_PREFERENCE;
|
||||
let mut opts = SslOptions::ALL
|
||||
| SslOptions::NO_COMPRESSION
|
||||
| SslOptions::NO_SSLV2
|
||||
| SslOptions::NO_SSLV3
|
||||
| SslOptions::SINGLE_DH_USE
|
||||
| SslOptions::SINGLE_ECDH_USE;
|
||||
opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
|
||||
ctx.set_options(opts);
|
||||
|
||||
let mut mode = ssl::SSL_MODE_AUTO_RETRY | ssl::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
|
||||
| ssl::SSL_MODE_ENABLE_PARTIAL_WRITE;
|
||||
let mut mode =
|
||||
SslMode::AUTO_RETRY | SslMode::ACCEPT_MOVING_WRITE_BUFFER | SslMode::ENABLE_PARTIAL_WRITE;
|
||||
|
||||
// This is quite a useful optimization for saving memory, but historically
|
||||
// caused CVEs in OpenSSL pre-1.0.1h, according to
|
||||
// https://bugs.python.org/issue25672
|
||||
if version::number() >= 0x1000108f {
|
||||
mode |= ssl::SSL_MODE_RELEASE_BUFFERS;
|
||||
if version::number() >= 0x1_00_01_08_0 {
|
||||
mode |= SslMode::RELEASE_BUFFERS;
|
||||
}
|
||||
|
||||
ctx.set_mode(mode);
|
||||
@ -56,41 +48,55 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
|
||||
Ok(ctx)
|
||||
}
|
||||
|
||||
/// A builder for `SslConnector`s.
|
||||
pub struct SslConnectorBuilder(SslContextBuilder);
|
||||
/// A type which wraps client-side streams in a TLS session.
|
||||
///
|
||||
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
|
||||
/// structures, configuring cipher suites, session options, hostname verification, and more.
|
||||
///
|
||||
/// OpenSSL's built in hostname verification is used when linking against OpenSSL 1.0.2 or 1.1.0,
|
||||
/// and a custom implementation is used when linking against OpenSSL 1.0.1.
|
||||
#[derive(Clone)]
|
||||
pub struct SslConnector(SslContext);
|
||||
|
||||
impl SslConnectorBuilder {
|
||||
impl SslConnector {
|
||||
/// Creates a new builder for TLS connections.
|
||||
///
|
||||
/// The default configuration is subject to change, and is currently derived from Python.
|
||||
pub fn new(method: SslMethod) -> Result<SslConnectorBuilder, ErrorStack> {
|
||||
pub fn builder(method: SslMethod) -> Result<SslConnectorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
ctx.set_default_verify_paths()?;
|
||||
// From https://github.com/python/cpython/blob/a170fa162dc03f0a014373349e548954fff2e567/Lib/ssl.py#L193
|
||||
ctx.set_cipher_list(
|
||||
"TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:\
|
||||
TLS13-AES-128-GCM-SHA256:\
|
||||
ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:\
|
||||
ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:\
|
||||
!aNULL:!eNULL:!MD5:!3DES",
|
||||
"DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK",
|
||||
)?;
|
||||
setup_verify(&mut ctx);
|
||||
|
||||
Ok(SslConnectorBuilder(ctx))
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "SslConnectorBuilder now implements Deref<Target=SslContextBuilder>")]
|
||||
pub fn builder(&self) -> &SslContextBuilder {
|
||||
self
|
||||
/// Initiates a client-side TLS session on a stream.
|
||||
///
|
||||
/// The domain is used for SNI and hostname verification.
|
||||
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
self.configure()?.connect(domain, stream)
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "SslConnectorBuilder now implements DerefMut<Target=SslContextBuilder>")]
|
||||
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
|
||||
self
|
||||
/// Returns a structure allowing for configuration of a single TLS session before connection.
|
||||
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
|
||||
Ssl::new(&self.0).map(|ssl| ConnectConfiguration {
|
||||
ssl,
|
||||
sni: true,
|
||||
verify_hostname: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for `SslConnector`s.
|
||||
pub struct SslConnectorBuilder(SslContextBuilder);
|
||||
|
||||
impl SslConnectorBuilder {
|
||||
/// Consumes the builder, returning an `SslConnector`.
|
||||
pub fn build(self) -> SslConnector {
|
||||
SslConnector(self.0.build())
|
||||
@ -111,101 +117,62 @@ impl DerefMut for SslConnectorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type which wraps client-side streams in a TLS session.
|
||||
///
|
||||
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
|
||||
/// structures, configuring cipher suites, session options, hostname verification, and more.
|
||||
///
|
||||
/// OpenSSL's built in hostname verification is used when linking against OpenSSL 1.0.2 or 1.1.0,
|
||||
/// and a custom implementation is used when linking against OpenSSL 1.0.1.
|
||||
#[derive(Clone)]
|
||||
pub struct SslConnector(SslContext);
|
||||
/// A type which allows for configuration of a client-side TLS session before connection.
|
||||
pub struct ConnectConfiguration {
|
||||
ssl: Ssl,
|
||||
sni: bool,
|
||||
verify_hostname: bool,
|
||||
}
|
||||
|
||||
impl SslConnector {
|
||||
/// Initiates a client-side TLS session on a stream.
|
||||
///
|
||||
/// The domain is used for SNI and hostname verification.
|
||||
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
self.configure()?.connect(domain, stream)
|
||||
impl ConnectConfiguration {
|
||||
/// A builder-style version of `set_use_server_name_indication`.
|
||||
pub fn use_server_name_indication(mut self, use_sni: bool) -> ConnectConfiguration {
|
||||
self.set_use_server_name_indication(use_sni);
|
||||
self
|
||||
}
|
||||
|
||||
/// Initiates a client-side TLS session on a stream without performing hostname verification.
|
||||
/// Configures the use of Server Name Indication (SNI) when connecting.
|
||||
///
|
||||
/// Defaults to `true`.
|
||||
pub fn set_use_server_name_indication(&mut self, use_sni: bool) {
|
||||
self.sni = use_sni;
|
||||
}
|
||||
|
||||
/// A builder-style version of `set_verify_hostname`.
|
||||
pub fn verify_hostname(mut self, verify_hostname: bool) -> ConnectConfiguration {
|
||||
self.set_verify_hostname(verify_hostname);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures the use of hostname verification when connecting.
|
||||
///
|
||||
/// Defaults to `true`.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// You should think very carefully before you use this method. If hostname verification is not
|
||||
/// used, *any* valid certificate for *any* site will be trusted for use from any other. This
|
||||
/// introduces a significant vulnerability to man-in-the-middle attacks.
|
||||
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
|
||||
S,
|
||||
>(
|
||||
&self,
|
||||
stream: S,
|
||||
) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
self.configure()?
|
||||
.danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication(stream)
|
||||
}
|
||||
|
||||
/// Returns a structure allowing for configuration of a single TLS session before connection.
|
||||
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
|
||||
Ssl::new(&self.0).map(ConnectConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
/// A type which allows for configuration of a client-side TLS session before connection.
|
||||
pub struct ConnectConfiguration(Ssl);
|
||||
|
||||
impl ConnectConfiguration {
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "ConnectConfiguration now implements Deref<Target=SslRef>")]
|
||||
pub fn ssl(&self) -> &Ssl {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "ConnectConfiguration now implements DerefMut<Target=SslRef>")]
|
||||
pub fn ssl_mut(&mut self) -> &mut Ssl {
|
||||
&mut self.0
|
||||
pub fn set_verify_hostname(&mut self, verify_hostname: bool) {
|
||||
self.verify_hostname = verify_hostname;
|
||||
}
|
||||
|
||||
/// Initiates a client-side TLS session on a stream.
|
||||
///
|
||||
/// The domain is used for SNI and hostname verification.
|
||||
/// The domain is used for SNI and hostname verification if enabled.
|
||||
pub fn connect<S>(mut self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
self.0.set_hostname(domain)?;
|
||||
setup_verify_hostname(&mut self.0, domain)?;
|
||||
if self.sni {
|
||||
self.ssl.set_hostname(domain)?;
|
||||
}
|
||||
|
||||
self.0.connect(stream)
|
||||
}
|
||||
if self.verify_hostname {
|
||||
setup_verify_hostname(&mut self.ssl, domain)?;
|
||||
}
|
||||
|
||||
/// Initiates a client-side TLS session on a stream without performing hostname verification.
|
||||
///
|
||||
/// The verification configuration of the connector's `SslContext` is not overridden.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// You should think very carefully before you use this method. If hostname verification is not
|
||||
/// used, *any* valid certificate for *any* site will be trusted for use from any other. This
|
||||
/// introduces a significant vulnerability to man-in-the-middle attacks.
|
||||
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
|
||||
S,
|
||||
>(
|
||||
self,
|
||||
stream: S,
|
||||
) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
self.0.connect(stream)
|
||||
self.ssl.connect(stream)
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,13 +180,126 @@ impl Deref for ConnectConfiguration {
|
||||
type Target = SslRef;
|
||||
|
||||
fn deref(&self) -> &SslRef {
|
||||
&self.0
|
||||
&self.ssl
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ConnectConfiguration {
|
||||
fn deref_mut(&mut self) -> &mut SslRef {
|
||||
&mut self.0
|
||||
&mut self.ssl
|
||||
}
|
||||
}
|
||||
|
||||
/// A type which wraps server-side streams in a TLS session.
|
||||
///
|
||||
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
|
||||
/// structures, configuring cipher suites, session options, and more.
|
||||
#[derive(Clone)]
|
||||
pub struct SslAcceptor(SslContext);
|
||||
|
||||
impl SslAcceptor {
|
||||
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
|
||||
/// considered a reasonable default choice.
|
||||
///
|
||||
/// This corresponds to the intermediate configuration of version 5 of Mozilla's server side TLS
|
||||
/// recommendations. See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
pub fn mozilla_intermediate_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1);
|
||||
let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?;
|
||||
ctx.set_tmp_dh(&dh)?;
|
||||
setup_curves(&mut ctx)?;
|
||||
ctx.set_cipher_list(
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:\
|
||||
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
|
||||
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
|
||||
)?;
|
||||
#[cfg(ossl111)]
|
||||
ctx.set_ciphersuites(
|
||||
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
/// Creates a new builder configured to connect to modern clients.
|
||||
///
|
||||
/// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations.
|
||||
/// See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
#[cfg(ossl111)]
|
||||
pub fn mozilla_modern_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
ctx.set_options(SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_3);
|
||||
ctx.set_ciphersuites(
|
||||
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
|
||||
/// considered a reasonable default choice.
|
||||
///
|
||||
/// This corresponds to the intermediate configuration of version 4 of Mozilla's server side TLS
|
||||
/// recommendations. See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
// FIXME remove in next major version
|
||||
pub fn mozilla_intermediate(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
ctx.set_options(SslOptions::CIPHER_SERVER_PREFERENCE);
|
||||
#[cfg(ossl111)]
|
||||
ctx.set_options(SslOptions::NO_TLSV1_3);
|
||||
let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?;
|
||||
ctx.set_tmp_dh(&dh)?;
|
||||
setup_curves(&mut ctx)?;
|
||||
ctx.set_cipher_list(
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:\
|
||||
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
|
||||
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:\
|
||||
ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:\
|
||||
ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:\
|
||||
DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
|
||||
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:\
|
||||
AES256-SHA:DES-CBC3-SHA:!DSS",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
/// Creates a new builder configured to connect to modern clients.
|
||||
///
|
||||
/// This corresponds to the modern configuration of version 4 of Mozilla's server side TLS recommendations.
|
||||
/// See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
// FIXME remove in next major version
|
||||
pub fn mozilla_modern(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
ctx.set_options(
|
||||
SslOptions::CIPHER_SERVER_PREFERENCE | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1,
|
||||
);
|
||||
#[cfg(ossl111)]
|
||||
ctx.set_options(SslOptions::NO_TLSV1_3);
|
||||
setup_curves(&mut ctx)?;
|
||||
ctx.set_cipher_list(
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:\
|
||||
ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
|
||||
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
/// Initiates a server-side TLS session on a stream.
|
||||
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
let ssl = Ssl::new(&self.0)?;
|
||||
ssl.accept(stream)
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,112 +307,6 @@ impl DerefMut for ConnectConfiguration {
|
||||
pub struct SslAcceptorBuilder(SslContextBuilder);
|
||||
|
||||
impl SslAcceptorBuilder {
|
||||
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
|
||||
/// considered a reasonable default choice.
|
||||
///
|
||||
/// This corresponds to the intermediate configuration of Mozilla's server side TLS
|
||||
/// recommendations. See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
pub fn mozilla_intermediate<I>(
|
||||
method: SslMethod,
|
||||
private_key: &PKeyRef,
|
||||
certificate: &X509Ref,
|
||||
chain: I,
|
||||
) -> Result<SslAcceptorBuilder, ErrorStack>
|
||||
where
|
||||
I: IntoIterator,
|
||||
I::Item: AsRef<X509Ref>,
|
||||
{
|
||||
let builder = SslAcceptorBuilder::mozilla_intermediate_raw(method)?;
|
||||
builder.finish_setup(private_key, certificate, chain)
|
||||
}
|
||||
|
||||
/// Creates a new builder configured to connect to modern clients.
|
||||
///
|
||||
/// This corresponds to the modern configuration of Mozilla's server side TLS recommendations.
|
||||
/// See its [documentation][docs] for more details on specifics.
|
||||
///
|
||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
pub fn mozilla_modern<I>(
|
||||
method: SslMethod,
|
||||
private_key: &PKeyRef,
|
||||
certificate: &X509Ref,
|
||||
chain: I,
|
||||
) -> Result<SslAcceptorBuilder, ErrorStack>
|
||||
where
|
||||
I: IntoIterator,
|
||||
I::Item: AsRef<X509Ref>,
|
||||
{
|
||||
let builder = SslAcceptorBuilder::mozilla_modern_raw(method)?;
|
||||
builder.finish_setup(private_key, certificate, chain)
|
||||
}
|
||||
|
||||
/// Like `mozilla_intermediate`, but does not load the certificate chain and private key.
|
||||
pub fn mozilla_intermediate_raw(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
let dh = Dh::from_pem(DHPARAM_PEM.as_bytes())?;
|
||||
ctx.set_tmp_dh(&dh)?;
|
||||
setup_curves(&mut ctx)?;
|
||||
ctx.set_cipher_list(
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
|
||||
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
|
||||
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
|
||||
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:\
|
||||
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:\
|
||||
ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:\
|
||||
ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:\
|
||||
DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
|
||||
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:\
|
||||
AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
/// Like `mozilla_modern`, but does not load the certificate chain and private key.
|
||||
pub fn mozilla_modern_raw(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ctx = ctx(method)?;
|
||||
setup_curves(&mut ctx)?;
|
||||
ctx.set_cipher_list(
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
|
||||
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
|
||||
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:\
|
||||
ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256",
|
||||
)?;
|
||||
Ok(SslAcceptorBuilder(ctx))
|
||||
}
|
||||
|
||||
fn finish_setup<I>(
|
||||
mut self,
|
||||
private_key: &PKeyRef,
|
||||
certificate: &X509Ref,
|
||||
chain: I,
|
||||
) -> Result<SslAcceptorBuilder, ErrorStack>
|
||||
where
|
||||
I: IntoIterator,
|
||||
I::Item: AsRef<X509Ref>,
|
||||
{
|
||||
self.0.set_private_key(private_key)?;
|
||||
self.0.set_certificate(certificate)?;
|
||||
self.0.check_private_key()?;
|
||||
for cert in chain {
|
||||
self.0.add_extra_chain_cert(cert.as_ref().to_owned())?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "SslAcceptorBuilder now implements Deref<Target=SslContextBuilder>")]
|
||||
pub fn builder(&self) -> &SslContextBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.9.23",
|
||||
note = "SslAcceptorBuilder now implements DerefMut<Target=SslContextBuilder>")]
|
||||
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Consumes the builder, returning a `SslAcceptor`.
|
||||
pub fn build(self) -> SslAcceptor {
|
||||
SslAcceptor(self.0.build())
|
||||
@ -353,247 +327,228 @@ impl DerefMut for SslAcceptorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
use ec::EcKey;
|
||||
use nid;
|
||||
|
||||
let curve = EcKey::from_curve_name(nid::X9_62_PRIME256V1)?;
|
||||
ctx.set_tmp_ecdh(&curve)
|
||||
}
|
||||
|
||||
#[cfg(ossl102)]
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
ctx._set_ecdh_auto(true)
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A type which wraps server-side streams in a TLS session.
|
||||
///
|
||||
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
|
||||
/// structures, configuring cipher suites, session options, and more.
|
||||
#[derive(Clone)]
|
||||
pub struct SslAcceptor(SslContext);
|
||||
|
||||
impl SslAcceptor {
|
||||
/// Initiates a server-side TLS session on a stream.
|
||||
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
|
||||
where
|
||||
S: Read + Write,
|
||||
{
|
||||
let ssl = Ssl::new(&self.0)?;
|
||||
ssl.accept(stream)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |p, x509| {
|
||||
let hostname = match x509.ssl() {
|
||||
Ok(Some(ssl)) => ssl.ex_data(*HOSTNAME_IDX),
|
||||
_ => None,
|
||||
};
|
||||
match hostname {
|
||||
Some(hostname) => verify::verify_callback(hostname, p, x509),
|
||||
None => p,
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
Ok(())
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
let param = ssl._param_mut();
|
||||
param.set_hostflags(::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
match domain.parse() {
|
||||
Ok(ip) => param.set_ip(ip),
|
||||
Err(_) => param.set_host(domain),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
let domain = domain.to_string();
|
||||
ssl.set_ex_data(*HOSTNAME_IDX, domain);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
mod verify {
|
||||
use std::net::IpAddr;
|
||||
use std::str;
|
||||
|
||||
use nid;
|
||||
use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContextRef};
|
||||
use stack::Stack;
|
||||
|
||||
pub fn verify_callback(
|
||||
domain: &str,
|
||||
preverify_ok: bool,
|
||||
x509_ctx: &X509StoreContextRef,
|
||||
) -> bool {
|
||||
if !preverify_ok || x509_ctx.error_depth() != 0 {
|
||||
return preverify_ok;
|
||||
} else if #[cfg(any(ossl102, libressl))] {
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
ctx.set_ecdh_auto(true)
|
||||
}
|
||||
} else {
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
|
||||
match x509_ctx.current_cert() {
|
||||
Some(x509) => verify_hostname(domain, &x509),
|
||||
None => true,
|
||||
let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
|
||||
ctx.set_tmp_ecdh(&curve)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
|
||||
match cert.subject_alt_names() {
|
||||
Some(names) => verify_subject_alt_names(domain, names),
|
||||
None => verify_subject_name(domain, &cert.subject_name()),
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl102, libressl261))] {
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify(SslVerifyMode::PEER);
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
|
||||
let ip = domain.parse();
|
||||
fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> {
|
||||
use x509::verify::X509CheckFlags;
|
||||
|
||||
for name in &names {
|
||||
match ip {
|
||||
Ok(ip) => {
|
||||
if let Some(actual) = name.ipaddress() {
|
||||
if matches_ip(&ip, actual) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
if let Some(pattern) = name.dnsname() {
|
||||
if matches_dns(pattern, domain, false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
let param = ssl.param_mut();
|
||||
param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
|
||||
match domain.parse() {
|
||||
Ok(ip) => param.set_ip(ip),
|
||||
Err(_) => param.set_host(domain),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
let domain = domain.to_string();
|
||||
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
|
||||
if let Some(pattern) = subject_name.entries_by_nid(nid::COMMONNAME).next() {
|
||||
let pattern = match str::from_utf8(pattern.data().as_slice()) {
|
||||
Ok(pattern) => pattern,
|
||||
Err(_) => return false,
|
||||
mod verify {
|
||||
use std::net::IpAddr;
|
||||
use std::str;
|
||||
|
||||
use ex_data::Index;
|
||||
use nid::Nid;
|
||||
use ssl::Ssl;
|
||||
use stack::Stack;
|
||||
use x509::{
|
||||
GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
|
||||
X509VerifyResult,
|
||||
};
|
||||
|
||||
// Unlike with SANs, IP addresses in the subject name don't have a
|
||||
// different encoding. We need to pass this down to matches_dns to
|
||||
// disallow wildcard matches with bogus patterns like *.0.0.1
|
||||
let is_ip = domain.parse::<IpAddr>().is_ok();
|
||||
|
||||
if matches_dns(&pattern, domain, is_ip) {
|
||||
return true;
|
||||
lazy_static! {
|
||||
pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
|
||||
if !preverify_ok || x509_ctx.error_depth() != 0 {
|
||||
return preverify_ok;
|
||||
}
|
||||
|
||||
fn matches_dns(mut pattern: &str, mut hostname: &str, is_ip: bool) -> bool {
|
||||
// first strip trailing . off of pattern and hostname to normalize
|
||||
if pattern.ends_with('.') {
|
||||
pattern = &pattern[..pattern.len() - 1];
|
||||
}
|
||||
if hostname.ends_with('.') {
|
||||
hostname = &hostname[..hostname.len() - 1];
|
||||
}
|
||||
let ok = match (
|
||||
x509_ctx.current_cert(),
|
||||
X509StoreContext::ssl_idx()
|
||||
.ok()
|
||||
.and_then(|idx| x509_ctx.ex_data(idx))
|
||||
.and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
|
||||
) {
|
||||
(Some(x509), Some(domain)) => verify_hostname(domain, &x509),
|
||||
_ => true,
|
||||
};
|
||||
|
||||
matches_wildcard(pattern, hostname, is_ip).unwrap_or_else(|| pattern == hostname)
|
||||
}
|
||||
if !ok {
|
||||
x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
|
||||
}
|
||||
|
||||
fn matches_wildcard(pattern: &str, hostname: &str, is_ip: bool) -> Option<bool> {
|
||||
// IP addresses and internationalized domains can't involved in wildcards
|
||||
if is_ip || pattern.starts_with("xn--") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let wildcard_location = match pattern.find('*') {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
|
||||
let wildcard_end = match dot_idxs.next() {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// Never match wildcards if the pattern has less than 2 '.'s (no *.com)
|
||||
//
|
||||
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
|
||||
// Chrome has a black- and white-list for this, but Firefox (via NSS) does
|
||||
// the same thing we do here.
|
||||
//
|
||||
// The Public Suffix (https://www.publicsuffix.org/) list could
|
||||
// potentially be used here, but it's both huge and updated frequently
|
||||
// enough that management would be a PITA.
|
||||
if dot_idxs.next().is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Wildcards can only be in the first component
|
||||
if wildcard_location > wildcard_end {
|
||||
return None;
|
||||
}
|
||||
|
||||
let hostname_label_end = match hostname.find('.') {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// check that the non-wildcard parts are identical
|
||||
if pattern[wildcard_end..] != hostname[hostname_label_end..] {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
let wildcard_prefix = &pattern[..wildcard_location];
|
||||
let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
|
||||
|
||||
let hostname_label = &hostname[..hostname_label_end];
|
||||
|
||||
// check the prefix of the first label
|
||||
if !hostname_label.starts_with(wildcard_prefix) {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
// and the suffix
|
||||
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
Some(true)
|
||||
}
|
||||
|
||||
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
|
||||
match (expected, actual.len()) {
|
||||
(&IpAddr::V4(ref addr), 4) => actual == addr.octets(),
|
||||
(&IpAddr::V6(ref addr), 16) => {
|
||||
let segments = [
|
||||
((actual[0] as u16) << 8) | actual[1] as u16,
|
||||
((actual[2] as u16) << 8) | actual[3] as u16,
|
||||
((actual[4] as u16) << 8) | actual[5] as u16,
|
||||
((actual[6] as u16) << 8) | actual[7] as u16,
|
||||
((actual[8] as u16) << 8) | actual[9] as u16,
|
||||
((actual[10] as u16) << 8) | actual[11] as u16,
|
||||
((actual[12] as u16) << 8) | actual[13] as u16,
|
||||
((actual[14] as u16) << 8) | actual[15] as u16,
|
||||
];
|
||||
segments == addr.segments()
|
||||
ok
|
||||
}
|
||||
|
||||
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
|
||||
match cert.subject_alt_names() {
|
||||
Some(names) => verify_subject_alt_names(domain, names),
|
||||
None => verify_subject_name(domain, &cert.subject_name()),
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
|
||||
let ip = domain.parse();
|
||||
|
||||
for name in &names {
|
||||
match ip {
|
||||
Ok(ip) => {
|
||||
if let Some(actual) = name.ipaddress() {
|
||||
if matches_ip(&ip, actual) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
if let Some(pattern) = name.dnsname() {
|
||||
if matches_dns(pattern, domain) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
|
||||
match subject_name.entries_by_nid(Nid::COMMONNAME).next() {
|
||||
Some(pattern) => {
|
||||
let pattern = match str::from_utf8(pattern.data().as_slice()) {
|
||||
Ok(pattern) => pattern,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
// Unlike SANs, IP addresses in the subject name don't have a
|
||||
// different encoding.
|
||||
match domain.parse::<IpAddr>() {
|
||||
Ok(ip) => pattern
|
||||
.parse::<IpAddr>()
|
||||
.ok()
|
||||
.map_or(false, |pattern| pattern == ip),
|
||||
Err(_) => matches_dns(pattern, domain),
|
||||
}
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool {
|
||||
// first strip trailing . off of pattern and hostname to normalize
|
||||
if pattern.ends_with('.') {
|
||||
pattern = &pattern[..pattern.len() - 1];
|
||||
}
|
||||
if hostname.ends_with('.') {
|
||||
hostname = &hostname[..hostname.len() - 1];
|
||||
}
|
||||
|
||||
matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname)
|
||||
}
|
||||
|
||||
fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> {
|
||||
// internationalized domains can't involved in wildcards
|
||||
if pattern.starts_with("xn--") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let wildcard_location = match pattern.find('*') {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
|
||||
let wildcard_end = match dot_idxs.next() {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// Never match wildcards if the pattern has less than 2 '.'s (no *.com)
|
||||
//
|
||||
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
|
||||
// Chrome has a black- and white-list for this, but Firefox (via NSS) does
|
||||
// the same thing we do here.
|
||||
//
|
||||
// The Public Suffix (https://www.publicsuffix.org/) list could
|
||||
// potentially be used here, but it's both huge and updated frequently
|
||||
// enough that management would be a PITA.
|
||||
if dot_idxs.next().is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Wildcards can only be in the first component
|
||||
if wildcard_location > wildcard_end {
|
||||
return None;
|
||||
}
|
||||
|
||||
let hostname_label_end = match hostname.find('.') {
|
||||
Some(l) => l,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// check that the non-wildcard parts are identical
|
||||
if pattern[wildcard_end..] != hostname[hostname_label_end..] {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
let wildcard_prefix = &pattern[..wildcard_location];
|
||||
let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
|
||||
|
||||
let hostname_label = &hostname[..hostname_label_end];
|
||||
|
||||
// check the prefix of the first label
|
||||
if !hostname_label.starts_with(wildcard_prefix) {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
// and the suffix
|
||||
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
|
||||
return Some(false);
|
||||
}
|
||||
|
||||
Some(true)
|
||||
}
|
||||
|
||||
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
|
||||
match *expected {
|
||||
IpAddr::V4(ref addr) => actual == addr.octets(),
|
||||
IpAddr::V6(ref addr) => actual == addr.octets(),
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::any::Any;
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
use std::error;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
@ -6,56 +7,82 @@ use std::io;
|
||||
|
||||
use error::ErrorStack;
|
||||
use ssl::MidHandshakeSslStream;
|
||||
use x509::X509VerifyResult;
|
||||
|
||||
/// An error code returned from SSL functions.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct ErrorCode(c_int);
|
||||
|
||||
impl ErrorCode {
|
||||
pub fn from_raw(raw: c_int) -> ErrorCode {
|
||||
ErrorCode(raw)
|
||||
}
|
||||
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// The SSL session has been closed.
|
||||
pub const ZERO_RETURN: ErrorCode = ErrorCode(ffi::SSL_ERROR_ZERO_RETURN);
|
||||
|
||||
/// An attempt to read data from the underlying socket returned `WouldBlock`.
|
||||
///
|
||||
/// Wait for read readiness and retry the operation.
|
||||
pub const WANT_READ: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_READ);
|
||||
|
||||
/// An attempt to write data to the underlying socket returned `WouldBlock`.
|
||||
///
|
||||
/// Wait for write readiness and retry the operation.
|
||||
pub const WANT_WRITE: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_WRITE);
|
||||
|
||||
/// A non-recoverable IO error occurred.
|
||||
pub const SYSCALL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SYSCALL);
|
||||
|
||||
/// An error occurred in the SSL library.
|
||||
pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL);
|
||||
|
||||
/// The client hello callback indicated that it needed to be retried.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
#[cfg(ossl111)]
|
||||
pub const WANT_CLIENT_HELLO_CB: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_CLIENT_HELLO_CB);
|
||||
}
|
||||
|
||||
/// An SSL error.
|
||||
// FIXME this is missing variants
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// The SSL session has been closed by the other end
|
||||
ZeroReturn,
|
||||
/// An attempt to read data from the underlying socket returned
|
||||
/// `WouldBlock`. Wait for read readiness and reattempt the operation.
|
||||
WantRead(io::Error),
|
||||
/// An attempt to write data from the underlying socket returned
|
||||
/// `WouldBlock`. Wait for write readiness and reattempt the operation.
|
||||
WantWrite(io::Error),
|
||||
/// The client certificate callback requested to be called again.
|
||||
WantX509Lookup,
|
||||
/// An error reported by the underlying stream.
|
||||
Stream(io::Error),
|
||||
/// An error in the OpenSSL library.
|
||||
pub(crate) enum InnerError {
|
||||
Io(io::Error),
|
||||
Ssl(ErrorStack),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(self.description())?;
|
||||
if let Some(err) = self.cause() {
|
||||
write!(fmt, ": {}", err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
/// An SSL error.
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
pub(crate) code: ErrorCode,
|
||||
pub(crate) cause: Option<InnerError>,
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::ZeroReturn => "The SSL session was closed by the other end",
|
||||
Error::WantRead(_) => "A read attempt returned a `WouldBlock` error",
|
||||
Error::WantWrite(_) => "A write attempt returned a `WouldBlock` error",
|
||||
Error::WantX509Lookup => "The client certificate callback requested to be called again",
|
||||
Error::Stream(_) => "The underlying stream reported an error",
|
||||
Error::Ssl(_) => "The OpenSSL library reported an error",
|
||||
impl Error {
|
||||
pub fn code(&self) -> ErrorCode {
|
||||
self.code
|
||||
}
|
||||
|
||||
pub fn io_error(&self) -> Option<&io::Error> {
|
||||
match self.cause {
|
||||
Some(InnerError::Io(ref e)) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::WantRead(ref err) => Some(err),
|
||||
Error::WantWrite(ref err) => Some(err),
|
||||
Error::Stream(ref err) => Some(err),
|
||||
Error::Ssl(ref err) => Some(err),
|
||||
pub fn into_io_error(self) -> Result<io::Error, Error> {
|
||||
match self.cause {
|
||||
Some(InnerError::Io(e)) => Ok(e),
|
||||
_ => Err(self),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ssl_error(&self) -> Option<&ErrorStack> {
|
||||
match self.cause {
|
||||
Some(InnerError::Ssl(ref e)) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -63,79 +90,93 @@ impl error::Error for Error {
|
||||
|
||||
impl From<ErrorStack> for Error {
|
||||
fn from(e: ErrorStack) -> Error {
|
||||
Error::Ssl(e)
|
||||
Error {
|
||||
code: ErrorCode::SSL,
|
||||
cause: Some(InnerError::Ssl(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error indicating that the operation can be immediately retried.
|
||||
///
|
||||
/// OpenSSL's [`SSL_read`] and [`SSL_write`] functions can return `SSL_ERROR_WANT_READ` even when
|
||||
/// the underlying socket is performing blocking IO in certain cases. When this happens, the
|
||||
/// the operation can be immediately retried.
|
||||
///
|
||||
/// To signal this event, the `io::Error` inside of [`Error::WantRead`] will be constructed around
|
||||
/// a `RetryError`.
|
||||
///
|
||||
/// [`SSL_read`]: https://www.openssl.org/docs/manmaster/man3/SSL_read.html
|
||||
/// [`SSL_write`]: https://www.openssl.org/docs/manmaster/man3/SSL_write.html
|
||||
/// [`Error::WantRead`]: enum.Error.html#variant.WantRead
|
||||
#[derive(Debug)]
|
||||
pub struct RetryError;
|
||||
|
||||
impl fmt::Display for RetryError {
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(error::Error::description(self))
|
||||
match self.code {
|
||||
ErrorCode::ZERO_RETURN => fmt.write_str("the SSL session has been shut down"),
|
||||
ErrorCode::WANT_READ => match self.io_error() {
|
||||
Some(_) => fmt.write_str("a nonblocking read call would have blocked"),
|
||||
None => fmt.write_str("the operation should be retried"),
|
||||
},
|
||||
ErrorCode::WANT_WRITE => match self.io_error() {
|
||||
Some(_) => fmt.write_str("a nonblocking write call would have blocked"),
|
||||
None => fmt.write_str("the operation should be retried"),
|
||||
},
|
||||
ErrorCode::SYSCALL => match self.io_error() {
|
||||
Some(err) => write!(fmt, "{}", err),
|
||||
None => fmt.write_str("unexpected EOF"),
|
||||
},
|
||||
ErrorCode::SSL => match self.ssl_error() {
|
||||
Some(e) => write!(fmt, "{}", e),
|
||||
None => fmt.write_str("OpenSSL error"),
|
||||
},
|
||||
ErrorCode(code) => write!(fmt, "unknown error code {}", code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for RetryError {
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"operation must be retried"
|
||||
"an OpenSSL error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match self.cause {
|
||||
Some(InnerError::Io(ref e)) => Some(e),
|
||||
Some(InnerError::Ssl(ref e)) => Some(e),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error or intermediate state after a TLS handshake attempt.
|
||||
// FIXME overhaul
|
||||
#[derive(Debug)]
|
||||
pub enum HandshakeError<S> {
|
||||
/// Setup failed.
|
||||
SetupFailure(ErrorStack),
|
||||
/// The handshake failed.
|
||||
Failure(MidHandshakeSslStream<S>),
|
||||
/// The handshake was interrupted midway through.
|
||||
/// The handshake encountered a `WouldBlock` error midway through.
|
||||
///
|
||||
/// This error will never be returned for blocking streams.
|
||||
// FIXME change to WouldBlock
|
||||
Interrupted(MidHandshakeSslStream<S>),
|
||||
WouldBlock(MidHandshakeSslStream<S>),
|
||||
}
|
||||
|
||||
impl<S: Any + fmt::Debug> StdError for HandshakeError<S> {
|
||||
impl<S: fmt::Debug> StdError for HandshakeError<S> {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
HandshakeError::SetupFailure(_) => "stream setup failed",
|
||||
HandshakeError::Failure(_) => "the handshake failed",
|
||||
HandshakeError::Interrupted(_) => "the handshake was interrupted",
|
||||
HandshakeError::WouldBlock(_) => "the handshake was interrupted",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&StdError> {
|
||||
fn cause(&self) -> Option<&dyn StdError> {
|
||||
match *self {
|
||||
HandshakeError::SetupFailure(ref e) => Some(e),
|
||||
HandshakeError::Failure(ref s) |
|
||||
HandshakeError::Interrupted(ref s) => Some(s.error()),
|
||||
HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => Some(s.error()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Any + fmt::Debug> fmt::Display for HandshakeError<S> {
|
||||
impl<S: fmt::Debug> fmt::Display for HandshakeError<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(StdError::description(self))?;
|
||||
match *self {
|
||||
HandshakeError::SetupFailure(ref e) => write!(f, ": {}", e)?,
|
||||
HandshakeError::Failure(ref s) |
|
||||
HandshakeError::Interrupted(ref s) => {
|
||||
HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => {
|
||||
write!(f, ": {}", s.error())?;
|
||||
if let Some(err) = s.ssl().verify_result() {
|
||||
write!(f, ": {}", err)?;
|
||||
let verify = s.ssl().verify_result();
|
||||
if verify != X509VerifyResult::OK {
|
||||
write!(f, ": {}", verify)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1402
openssl/src/ssl/test/mod.rs
Normal file
1402
openssl/src/ssl/test/mod.rs
Normal file
File diff suppressed because it is too large
Load Diff
167
openssl/src/ssl/test/server.rs
Normal file
167
openssl/src/ssl/test/server.rs
Normal file
@ -0,0 +1,167 @@
|
||||
use std::io::{Read, Write};
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream};
|
||||
use std::thread::{self, JoinHandle};
|
||||
|
||||
use ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslRef, SslStream};
|
||||
|
||||
pub struct Server {
|
||||
handle: Option<JoinHandle<()>>,
|
||||
addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl Drop for Server {
|
||||
fn drop(&mut self) {
|
||||
if !thread::panicking() {
|
||||
self.handle.take().unwrap().join().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn builder() -> Builder {
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
ctx.set_certificate_chain_file("test/cert.pem").unwrap();
|
||||
ctx.set_private_key_file("test/key.pem", SslFiletype::PEM)
|
||||
.unwrap();
|
||||
|
||||
Builder {
|
||||
ctx,
|
||||
ssl_cb: Box::new(|_| {}),
|
||||
io_cb: Box::new(|_| {}),
|
||||
should_error: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client(&self) -> ClientBuilder {
|
||||
ClientBuilder {
|
||||
ctx: SslContext::builder(SslMethod::tls()).unwrap(),
|
||||
addr: self.addr,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect_tcp(&self) -> TcpStream {
|
||||
TcpStream::connect(self.addr).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Builder {
|
||||
ctx: SslContextBuilder,
|
||||
ssl_cb: Box<dyn FnMut(&mut SslRef) + Send>,
|
||||
io_cb: Box<dyn FnMut(SslStream<TcpStream>) + Send>,
|
||||
should_error: bool,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
pub fn ctx(&mut self) -> &mut SslContextBuilder {
|
||||
&mut self.ctx
|
||||
}
|
||||
|
||||
pub fn ssl_cb<F>(&mut self, cb: F)
|
||||
where
|
||||
F: 'static + FnMut(&mut SslRef) + Send,
|
||||
{
|
||||
self.ssl_cb = Box::new(cb);
|
||||
}
|
||||
|
||||
pub fn io_cb<F>(&mut self, cb: F)
|
||||
where
|
||||
F: 'static + FnMut(SslStream<TcpStream>) + Send,
|
||||
{
|
||||
self.io_cb = Box::new(cb);
|
||||
}
|
||||
|
||||
pub fn should_error(&mut self) {
|
||||
self.should_error = true;
|
||||
}
|
||||
|
||||
pub fn build(self) -> Server {
|
||||
let ctx = self.ctx.build();
|
||||
let socket = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = socket.local_addr().unwrap();
|
||||
let mut ssl_cb = self.ssl_cb;
|
||||
let mut io_cb = self.io_cb;
|
||||
let should_error = self.should_error;
|
||||
|
||||
let handle = thread::spawn(move || {
|
||||
let socket = socket.accept().unwrap().0;
|
||||
let mut ssl = Ssl::new(&ctx).unwrap();
|
||||
ssl_cb(&mut ssl);
|
||||
let r = ssl.accept(socket);
|
||||
if should_error {
|
||||
r.unwrap_err();
|
||||
} else {
|
||||
let mut socket = r.unwrap();
|
||||
socket.write_all(&[0]).unwrap();
|
||||
io_cb(socket);
|
||||
}
|
||||
});
|
||||
|
||||
Server {
|
||||
handle: Some(handle),
|
||||
addr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientBuilder {
|
||||
ctx: SslContextBuilder,
|
||||
addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl ClientBuilder {
|
||||
pub fn ctx(&mut self) -> &mut SslContextBuilder {
|
||||
&mut self.ctx
|
||||
}
|
||||
|
||||
pub fn build(self) -> Client {
|
||||
Client {
|
||||
ctx: self.ctx.build(),
|
||||
addr: self.addr,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(self) -> SslStream<TcpStream> {
|
||||
self.build().builder().connect()
|
||||
}
|
||||
|
||||
pub fn connect_err(self) {
|
||||
self.build().builder().connect_err();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
ctx: SslContext,
|
||||
addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn builder(&self) -> ClientSslBuilder {
|
||||
ClientSslBuilder {
|
||||
ssl: Ssl::new(&self.ctx).unwrap(),
|
||||
addr: self.addr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientSslBuilder {
|
||||
ssl: Ssl,
|
||||
addr: SocketAddr,
|
||||
}
|
||||
|
||||
impl ClientSslBuilder {
|
||||
pub fn ssl(&mut self) -> &mut SslRef {
|
||||
&mut self.ssl
|
||||
}
|
||||
|
||||
pub fn connect(self) -> SslStream<TcpStream> {
|
||||
let socket = TcpStream::connect(self.addr).unwrap();
|
||||
let mut s = self.ssl.connect(socket).unwrap();
|
||||
s.read_exact(&mut [0]).unwrap();
|
||||
s
|
||||
}
|
||||
|
||||
pub fn connect_err(self) {
|
||||
let socket = TcpStream::connect(self.addr).unwrap();
|
||||
self.ssl.connect(socket).unwrap_err();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user