-
Notifications
You must be signed in to change notification settings - Fork 15
/
README-SDK
305 lines (256 loc) · 13.1 KB
/
README-SDK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
AmiSSL v5 Developer Documentation
---------------------------------
1. Introduction
2. AmiSSL API
3. Subprocesses
4. Examples
5. Link libraries
6. Migration from AmiSSL v4
7. Migration from AmiSSL v3
8. Differences to OpenSSL
9. Callback functions
10. Stub functions
11. VBCC issues
12. SAS/C issues
1. Introduction
---------------
This archive contains developer files and example programs which should make
it possible to add AmiSSL support to client and server applications interested
in providing SSL/TLS functionality to end users. This SDK release provides
include files for GCC and vbcc for OS3/m68k and OS4/PPC. Also, SAS/C is
supported, but please see the end of this document for important information.
The information given here is mostly AmiSSL specific. For more information on
OpenSSL programming, check the OpenSSL documentation and examples
(https://www.openssl.org/).
2. AmiSSL API
-------------
The AmiSSL v5 API is slightly different from previous versions and has been
simplified. The procedure to use AmiSSL should be something like the following
pseudo-code:
-- cut here --
#include <proto/amisslmaster.h>
#include <proto/amissl.h>
#include <libraries/amisslmaster.h>
#include <libraries/amissl.h>
#include <amissl/amissl.h>
if((AmiSSLMasterBase = OpenLibrary("amisslmaster.library",
AMISSLMASTER_MIN_VERSION))
{
#if defined(__amigaos4__)
if(IAmiSSLMaster = (struct AmiSSLMasterIFace *)
GetInterface((struct Library *)AmiSSLMasterBase,
"main", 1, NULL))
{
if(OpenAmiSSLTags(AMISSL_CURRENT_VERSION,
AmiSSL_UsesOpenSSLStructs, TRUE or FALSE,
AmiSSL_GetIAmiSSL, &IAmiSSL,
AmiSSL_ISocket, ISocket,
AmiSSL_ErrNoPtr, &errno,
..., TAG_DONE) == 0)
{
CloseAmiSSL();
}
else printf("ERROR: Couldn't open AmiSSL!");
DropInterface((struct Interface *)IAmiSSLMaster);
}
else printf("ERROR: Couldn't obtain AmiSSLMaster interface!");
#else
if(OpenAmiSSLTags(AMISSL_CURRENT_VERSION,
AmiSSL_UsesOpenSSLStructs, TRUE or FALSE,
AmiSSL_GetAmiSSLBase, &AmiSSLBase,
AmiSSL_GetAmiSSLExtBase, &AmiSSLExtBase,
AmiSSL_SocketBase, SocketBase,
AmiSSL_ErrNoPtr, &errno,
..., TAG_DONE) == 0)
{
CloseAmiSSL();
}
else printf("ERROR: Couldn't open AmiSSL!");
#endif
CloseLibrary(AmiSSLMasterBase);
}
else printf("ERROR: Couldn't open amisslmaster.library!");
-- cut here --
The first step is to open amisslmaster.library requesting at least
AMISSLMASTER_MIN_VERSION version (and, for OS4, call GetInterface() to get the
"main" interface and later DropInterface() in the cleanup phase).
Then amisslmaster.library/OpenAmiSSLTags() has to be called specifying which
API version the program was compiled for and whether it uses OpenSSL structures
in some way (ie. if it accesses some of the fields directly and not through
AmiSSL API or if it includes OpenSSL structures in its own structures - if
unsure, specify TRUE). It will return zero on success or a non-zero value on
failure. See the autodocs for amisslmaster.library/OpenAmiSSLTags() and
amissl.library/InitAmiSSL() for currently available tags.
If you need to compile a program specifically for f. ex. OpenSSL 0.9.7g API,
you need to use the SDK in which AMISSL_CURRENT_VERSION is AMISSL_V097g. If
you are, however, always using the latest AmiSSL SDK version you can keep
using AMISSL_CURRENT_VERSION.
The use of amisslmaster.library makes it possible to have multiple versions of
amissl.library with incompatible APIs installed keeping the programs compiled
with an older amissl.library working. This is necessary since OpenSSL API
changes from time to time. Also, when a new version of AmiSSL is released with
amissl.library API that is backwards compatible to some previous version, a
program requesting the old version of amissl.library will automatically get
the new version and the old version can be deleted.
3. Subprocesses
---------------
Note, that unlike in AmiSSL v1, AmiSSLBase can be shared between different
subprocesses. Furthermore, this is encouraged since it allows the cache of
server certificates to be used by all subprocesses that share the same AmiSSL
base resulting in speed increase. Each subprocess must call InitAmiSSL() with
appropriate arguments before using any other amissl.library calls and
CleanupAmiSSL() before it exits. AmiSSL then ensures due to its baserel-based
environment that any opener receives an own baserel based library base.
4. Examples
-----------
The provided example, httpget.c, is an example of how to use the new
OpenSSL 3.x built-in HTTP client functions. It shows how to retrieve a
document from a "http://" or "https://" server, with or without a password
and how you can also use the URL parsing functions from OpenSSL 3.x.
Another example, https.c, is a very simple client. It shows how to retrieve a
document from a "https://" server, at a lower level, by connecting directly
to the site, and also by connecting through a proxy server (SSL tunneling).
5. Link libraries
-----------------
The following optional link libraries are supplied, for GCC on OS3/OS4 and
vbcc on OS4:
- libamisslauto.a (link with -lamisslauto)
As per the standard libauto, automatically open and set up AmiSSL, without
having to worry about the initialisation code yourself. You may also compile
your own link library for a different compiler from lib/autoinit_amissl_main.c
which can be compiled with VBCC, SAS/C and GCC.
- libamisslstubs.a (link with -lamisslstubs)
Some OpenSSL functions take a pointer to another OpenSSL function as a
parameter. This becomes a problem when using standard AmigaOS library inlines,
usually causing undefined reference errors (e.g. X509_free) when linking. You
can either create your own stub functions to resolve this, which simply call
the AmiSSL functions, but for convenience you can instead link with this
library which contains stubs for all OpenSSL functions. If you wish to create
this library for a different compiler, the stubs source code can be created
on OS4 using "idltool -L amissl.xml" or on OS3 from the sfd file using tools
such as sfdc, sfd or fd2pragma.
6. Migration from AmiSSL v4
---------------------------
AmiSSL v4 is OpenSSL 1.1.x based, whilst AmiSSL v5 uses OpenSSL 3.x, but
fortunately you will not usually need to make any changes to your code, as most
things are actually backwards compatible (most functions that have been removed
or changed will be replaced by macros in the OpenSSL header files). However, we
encourage developers to use the new OpenAmiSSLTags() function, in place of
InitAmiSSLMaster(), OpenAmiSSL() and InitAmiSSL() (these functions will still
continue to operate as before). Details of OpenSSL changes are available at
https://www.openssl.org/docs/manmaster/man7/migration_guide.html and with
GCC you will receive warnings if you use any deprecated functions.
Due to the shear amount of OpenSSL 3.x API functions available, we had to split
them across two library bases on OS3 which meant the addition of AmiSSLExtBase.
AmiSSLExtBase can be obtained using the AmiSSL_GetAmiSSLExtBase tag in
OpenAmiSSLTags() (or alternatively, in InitAmiSSL() if you wish to keep using
the old functions). This does not apply to OS4, where there is one single
interface as before.
The procedure for subprocesses remains unchanged - they must continue to call
InitAmiSSL() and CleanupAmiSSL() if sharing the AmiSSL instance from the parent
task where OpenAmiSSLTags() was called.
7. Migration from AmiSSL v3
---------------------------
AmiSSL v3 is OpenSSL 0.9.x based and there were many fundamental changes in
AmiSSL v4 due to the switch to OpenSSL 1.1.x. Although there were no changes in
the AmiSSL API itself, there were lots of important changes in the OpenSSL API.
Rather than simply recompiling, depending on how heavy your OpenSSL usage is,
you may well need to make changes to your code. For example, many public
structures that were defined in the header files have now been made private.
Rather than allocating them yourself, or putting them on the stack, you will
need to use the provided new functions to obtain, access and modify these
structures. We also dropped SSLv2/v3 methods completely, so you will need to
switch to TLS.
8. Differences to OpenSSL
-------------------------
AmiSSL provides essentially the same functionality as OpenSSL, but there are a
few differences as a result of the Amiga shared library model and necessity to
support different compilers. Unlike AmiSSL v1, AmiSSL v3/v4/v5 uses
"#include <openssl/xxx.h>" scheme instead of "#include <amissl/xxx.h>" scheme.
This and some other changes should make it possible to compile most OpenSSL
programs out of the box.
The functions, e.g., BIO_set_fp(), BIO_get_fp() and BIO_new_fp() are not
available since they require a FILE * argument which is C runtime library
specific. However, there are replacement functions which have _amiga added to
their name and take a BPTR instead of FILE * argument. For example,
BIO_set_fp(bio_out, stdout, BIO_NOCLOSE) can be replaced by
BIO_set_fp_amiga(bio_out, Output(), BIO_NOCLOSE);
Also, all other stdio functions that have a FILE * argument are not available.
However, all these functions have an equivalent that accepts BIO * instead of
FILE * so these functions can be used instead. The simple sequence
-- cut here --
fp = fopen(file, mode);
openssl_func_fp(fp, ...);
fclose(fp)
-- cut here --
sequence can be replaced with the following:
-- cut here --
bio = BIO_new_file(file, mode);
openssl_func(bio, ...);
BIO_free(bio);
-- cut here --
In addition, AmiSSL adds several functions which deal with OpenSSL ciphers:
const char *SSL_CIPHER_get_mac(SSL_CIPHER *cipher);
const char *SSL_CIPHER_get_encryption(SSL_CIPHER *cipher);
const char *SSL_CIPHER_get_authentication(SSL_CIPHER *cipher);
const char *SSL_CIPHER_get_key_exchange(SSL_CIPHER *cipher);
const char *SSL_CIPHER_get_export(SSL_CIPHER *cipher);
These will return textual representation of requested cipher data. For example,
SSL_CIPHER_get_encryption() will return "AES(256)" when 256-bit AES cipher is
used.
9. Callback functions
---------------------
Some OpenSSL functions require you to pass your own callback function in as a
parameter. These functions will be called using default calling conventions
on OS3 and OS4. On OS3 this means AmiSSL will call your function with the
function arguments placed on the stack, whilst on OS4 they will be placed in
registers, as usual. If you have set your compiler to use a different
convention, be sure to define your callback function correctly. For example:
STDARGS SAVEDS int verify_cb(int preverify_ok, X509_STORE_CTX *ctx)
{
return preverify_ok;
}
SSL_CTX_set_verify(sslctx,SSL_VERIFY_PEER,verify_cb);
10. Stub functions
------------------
Sometimes it is necessary to pass an AmiSSL function as a function pointer
argument. Since AmiSSL functions are inside the library, it is not possible
directly. See the section about the libamisslstubs.a link library which aims to
solve this issue. However, if not using the link library, it is possible to
write your own stub function:
void NOSTACKCHECK /* STDARGS */ SAVEDS (ASN1_OBJECT_free)(ASN1_OBJECT *a)
{
ASN1_OBJECT_free(a);
}
In newly written code it is better to use a different name for the function,
but when working with already existing code it might be easier to use the same
name than to change many occurrences of f. ex. ASN1_OBJECT_free to f. ex.
ASN1_OBJECT_free_stub whenever ASN1_OBJECT_free is passed as a function
pointer.
11. VBCC issues
---------------
The OpenSSL header files rely on using and declaring static inline helper
functions. This means that lots of functions will be declared in every
module that you include the OpenSSL headers and probably most of them you
will not use or need. Most compilers remove these unused functions by
default and sometimes even with the optimiser completely disabled.
Unfortunately, VBCC is different and will only remove these functions if
you use -O3 when compiling. -O1 and -O2 will leave all the unused functions
in your code. If for some reason you do not wish to use -O3, you could try
-O=17375 or -O=17407. These are the equivalent of -O1 and -O2 respectively,
but with the required optimiser bit added to enable removal of the unused
functions. Alternatively, you may compile with -DAMISSL_NO_STATIC_FUNCTIONS,
which will stop all the affected functions from being declared in the first
place, but obviously you can only use this if your code is not using any of
these functions otherwise you will get errors when compiling.
12. SAS/C issues
----------------
You will need to add "MemorySize=h IdentifierLength=80" to your SC command
line and have to take special care where 64-bit integers are concerned. In
particular, OPENSSL_init_ssl(), which you mignt not even be calling directly,
but is ultimately the end result of many of the macros for older legacy SSL
initialisation functions. Remember that for 64-bit parameters, the high
32-bits are placed in D0 and the low 32-bits in D1. So, you might want to
use a workaround like this:
#define OPENSSL_init_ssl_32(opts, settings) \
(putreg(REG_D1,opts), OPENSSL_init_ssl(0, settings))