~ubuntu-branches/ubuntu/oneiric/osptoolkit/oneiric

« back to all changes in this revision

Viewing changes to enroll/osptnepenroll.h

  • Committer: Bazaar Package Importer
  • Author(s): TransNexus, Inc.
  • Date: 2007-12-30 20:37:26 UTC
  • Revision ID: james.westby@ubuntu.com-20071230203726-dysah2e93yqd3vbp
Tags: upstream-3.4.2
ImportĀ upstreamĀ versionĀ 3.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
*** COPYRIGHT (c) 2002 by TransNexus, Inc.                              ***
 
3
***                                                                     ***
 
4
*** This software is property of TransNexus, Inc.                       ***
 
5
*** This software is freely available under license from TransNexus.    ***
 
6
*** The license terms and conditions for free use of this software by   ***
 
7
*** third parties are defined in the OSP Toolkit Software License       ***
 
8
*** Agreement (LICENSE.txt).  Any use of this software by third         ***
 
9
*** parties, which does not comply with the terms and conditions of the ***
 
10
*** OSP Toolkit Software License Agreement is prohibited without        ***
 
11
*** the prior, express, written consent of TransNexus, Inc.             ***
 
12
***                                                                     ***
 
13
*** Thank you for using the OSP ToolKit(TM).  Please report any bugs,   ***
 
14
*** suggestions or feedback to support@transnexus.com                   ***
 
15
***                                                                     ***
 
16
**************************************************************************/
 
17
 
 
18
 
 
19
 
 
20
 
 
21
 
 
22
 
 
23
 
 
24
#include "osp/osposincl.h"
 
25
#include "openssl/ssl.h"
 
26
 
 
27
/* This is the "operation" parameter that is sent in each request: */
 
28
#define OSPC_ENROLL_OPERATION_REQ_PARAM   "operation"
 
29
 
 
30
/* These are the possible values of the "operation" parameter: */
 
31
#define OSPC_ENROLL_OP_REQUEST_REQ_PARAM  "request"
 
32
#define OSPC_ENROLL_OP_RETRIEVE_REQ_PARAM "retrieve"
 
33
#define OSPC_ENROLL_OP_CA_CERT_REQ_PARAM  "getcacert"
 
34
 
 
35
/* These are the constants that may be returned in a response: */
 
36
#define OSPC_ENROLL_CA_CERT_RSP_PARAM     "certificate"
 
37
 
 
38
/* These are also the parameters that are sent in each certificate request
 
39
 * or retrieval: 
 
40
 */
 
41
#define OSPC_ENROLL_NONCE_REQ_PARAM       "nonce"
 
42
#define OSPC_ENROLL_USERNAME_REQ_PARAM    "username"
 
43
#define OSPC_ENROLL_PASSWORD_REQ_PARAM    "password"
 
44
#define OSPC_ENROLL_DEVICEID_REQ_PARAM    "device"
 
45
#define OSPC_ENROLL_CUSTOMERID_REQ_PARAM  "customer"
 
46
#define OSPC_ENROLL_CERT_REQ_PARAM        "request"
 
47
 
 
48
#define OSPC_ENROLL_CERT_RSP_PARAM        "cert"
 
49
#define OSPC_ENROLL_STATUS_RSP_PARAM      "status"
 
50
 
 
51
/* These signify successful and pending certificate requests, respectively: */
 
52
#define OSPC_ENROLL_STATUS_OK             0
 
53
#define OSPC_ENROLL_STATUS_PENDING        1
 
54
 
 
55
/* Denotes the failure of an enrollment request; this may happen even
 
56
 * if there aren't any problems with the enrollment client:
 
57
 */
 
58
#define OSPC_ENROLL_STATUS_FAILURE_DEFAULT 2
 
59
 
 
60
 
 
61
/* The possible field delimiters in a URL are an ampersand ( '&' ) and
 
62
 * a space, which would indicate some other field. Actually, this is true
 
63
 * for any whitespace character.
 
64
 */
 
65
#define OSPC_ENROLL_FIELD_DELIMITERS      "& "
 
66
 
 
67
/* The "normal" field delimiter for a url is an ampersand: */
 
68
#define OSPC_ENROLL_FIELD_DELIMITER       "&"
 
69
 
 
70
/* This separates names and values in an url. For example, 
 
71
 * in http://www.transnexus.com/some_path/enroll?name=value&another_name=x ,
 
72
 * the name and value in the HTTP get would be the '='.
 
73
 */
 
74
#define OSPC_ENROLL_NAME_VALUE_DELIMITER  "="
 
75
 
 
76
/* The content type of the message we post to the enrollment server: */
 
77
#define OSPC_ENROLL_CONTENT_TYPE          "text/html"
 
78
 
 
79
/* What is the maximum length of the request that could be transmitted?
 
80
 * This needs to take into account the maximum size of a 
 
81
 * RelativeDistinguishedName ( say, 2KB ), the size of a subjectPublicKeyInfo
 
82
 * and a signature ( 512 bytes, for 2 2048-bit values ), and the size
 
83
 * of the attributes and other cert request chaff ( say, less than 512 bytes ).
 
84
 * If we base64-encode this, then we get a max of about 4KB.
 
85
 */
 
86
#define OSPC_ENROLL_MAX_REQUEST_SIZE      4096
 
87
 
 
88
/* How long will the nonce be in bytes? */
 
89
#define OSPC_ENROLL_NONCE_LEN             16 
 
90
 
 
91
#ifdef __cplusplus
 
92
extern "C" 
 
93
{
 
94
#endif
 
95
 
 
96
/* 
 
97
 * Given the input parameters for enrollment, setup all of the communications
 
98
 * and structures for enrollment and then send a request to the enrollment
 
99
 * server. The results should be stored in the ospvEnrollStatusOUt
 
100
 * ( failed, pending, or success ) and ospvLocalCertOut ( if the request
 
101
 * was successful.
 
102
 */
 
103
int OSPPEnroll( 
 
104
    OSPTENROLLPARAMS* ospvEnrollParamsIn,
 
105
    OSPTCOMMPARAMS*   ospvCommParamsIn,
 
106
    unsigned char**   ospvLocalCertOut,
 
107
    unsigned*         ospvLocalCertLenOut,
 
108
    unsigned*         ospvEnrollStatusOut
 
109
);
 
110
 
 
111
/* Given the enrollment parameters, base64-decode the CACertB64 parameter
 
112
 * of the enrollment parmaeters and place the binary CA certificate in the
 
113
 * CACert field of the enrollment parameters instead.
 
114
 *
 
115
 * Input: pointer to the enrollment parameters, which should contain a pointer
 
116
 *        the base64-encoded CA certificate and its length, as well as pointers
 
117
 *        to the binary CA certificate and its length ( which will initially
 
118
 *        be NULL and 0. )
 
119
 *
 
120
 * Output: OSPC_ERR_NO_ERROR is returned if there are no problems,  or
 
121
 *         a non-OSPC_ERR_NO_ERROR value is returned. If everything is
 
122
 *         successful, then the CACertB64 field should be populated as well.
 
123
 */
 
124
int OSPPBase64DecodeCACert(
 
125
    OSPTENROLLPARAMS* ospvEnrollParamsIn
 
126
);
 
127
 
 
128
/*
 
129
 * Create an enrollment request for requesting or retrieving a certificate, 
 
130
 * send the request to the enrollment server ( using the communications 
 
131
 * manager passed in ); extract the status and certificate from the
 
132
 * response, validate the certificate, and return the certificate.
 
133
 */
 
134
int OSPPEnrollDevice (
 
135
    OSPTCOMM*       ospvCommMgr,
 
136
    OSPTMSGINFO*    ospvEnrollMsg,
 
137
    OSPTASN1OBJECT* ospvRequestPublicKeyIn,
 
138
    unsigned*       ospvEnrollStatusOut,
 
139
    unsigned char** ospvCertOut,
 
140
    unsigned*       ospvCertLenOut
 
141
);
 
142
 
 
143
/*
 
144
 * Given a certificate for a device that has been received, validate it
 
145
 * against the public key used ( to be added ), the CA certificate that
 
146
 * we expected to sign it, and its general construction. The certificate
 
147
 * is placed in *ospvCertOut.
 
148
 */
 
149
int OSPPValidateDeviceCert (
 
150
    OSPTSEC*        ospvSecIn,
 
151
    OSPTASN1OBJECT* ospvRequestPublicKeyIn,
 
152
    unsigned char*  ospvCertB64In,
 
153
    unsigned char** ospvCertOut,
 
154
    unsigned*       ospvCertLenOut 
 
155
);
 
156
 
 
157
 
 
158
int OSPPCreateEnrollmentRequestHeader(
 
159
    OSPTMSGINFO* ospvEnrollmentReqMsgInfo
 
160
);
 
161
 
 
162
int OSPPCreateEnrollmentRequestBody(
 
163
    unsigned char**   ospvRequestBfrOut,
 
164
    OSPTENROLLPARAMS* ospvEnrollParamsIn
 
165
);
 
166
 
 
167
/* 
 
168
 * Create a nonce value that will serve for both stronger encryption ( to
 
169
 * eliminate known-ciphertext attacks ) and for preventing flooding at the
 
170
 * server. This isn't required by an enrollment server, but it is recommended.
 
171
 *
 
172
 * Input: references to the nonce's character string and the nonce's length;
 
173
 *        both are set on output. 
 
174
 *
 
175
 * Output: success in generating the nonce: OSPC_ERR_NO_ERROR if successful,
 
176
 *         another value otherwise. *ospvNonce should be allocated a block
 
177
 *         of memory whose length is specified by ospvNonceLenIn. Note that
 
178
 *         existing memory will not be used.
 
179
 * 
 
180
 */
 
181
int OSPPFillBufWithRandomBytes( 
 
182
    unsigned char*  ospvNonce,
 
183
    unsigned*       ospvNonceLenOut,
 
184
    unsigned        ospvNonceLenIn
 
185
);
 
186
 
 
187
/* Check all of the enrollment parameters for any problems that might cause
 
188
 * it to be rejected by an enrollment server. We'll check that the
 
189
 * username and password are alphanumeric, that the customer and device ids
 
190
 * are numeric, and that the base64-encoded certificate request exists
 
191
 * ( the contents of the base64-encoded certificate request are validated 
 
192
 * elsewhere. ) We'll get an error if any of these values are empty or null.
 
193
 *
 
194
 * Input: reference to the enrollment parameters
 
195
 *
 
196
 * Output: OSPC_ERR_NO_ERROR if all of the parameters are non-null, non-empty,
 
197
 *         and have the appropriate type. Otherwise, an error code other
 
198
 *         than OSPC_ERR_NO_ERROR will be returned.
 
199
 */
 
200
int OSPPCheckEnrollmentParams (
 
201
    OSPTENROLLPARAMS* ospvEnrollParams
 
202
);
 
203
 
 
204
/* 
 
205
 * Given a pointer to some enrollment parameters, check the validity of each
 
206
 * parameter for requesting a certificate. This function returns an error
 
207
 * if any of the values are invalid.
 
208
 *
 
209
 * Input: pointer to an enrollment parameter list; there is only one structure,
 
210
 *        and the use of the reference is done for the sake of efficiency.
 
211
 *
 
212
 * Output: OSPC_ERR_NO_ERROR if all of the parameters can be used in a cert
 
213
 *         request; otherwise, an error is returned.
 
214
 */
 
215
int OSPPCheckEnrollmentRequestParams( 
 
216
    OSPTENROLLPARAMS* ospvEnrollParams 
 
217
);
 
218
 
 
219
/* Given a pointer to a string to write, and a pointer to its length, and
 
220
 * the length of a nonce to generate, generate a nonce and place it in the
 
221
 * output string and its referenced length. The nonce will be binary, not
 
222
 * ASCII.
 
223
 *
 
224
 * This function will use OSPPFillBufWithRandomBytes, which in turn
 
225
 * relies on OSPPUtilGetRandom, for generating the random bytes of the nonce. 
 
226
 * Since OSPPUtilGetRandom doesn't rely on anything special for the
 
227
 * entropy of these random values, it would be best to either modify 
 
228
 * OSPPUtilGetRandom or just pass the value of the nonce in ( so that we
 
229
 * don't generate it here. )
 
230
 *
 
231
 * Input: reference to a string and its length to write to, as well as a
 
232
 *        length that specifies how long the nonce should be.
 
233
 *
 
234
 * Output: OSPC_ERR_NO_ERROR if there aren't any problems; in this case, 
 
235
 *         the *ospvNonceOut should be non-null and *ospvNonceLenOut should
 
236
 *         specify its length. Otherwise, an error code other than 
 
237
 *         OSPC_ERR_NO_ERROR will be returned if a problem comes up. In this
 
238
 *         case, *ospvNonceOut should be OSPC_OSNULL and *ospvNonceLenOut
 
239
 *         should be 0 ( but this isn't guaranteed, especially if 
 
240
 *         ospvNonceOut or ospvNonceLenOut were OSPC_OSNULL to begin with. )
 
241
 */
 
242
int OSPPCreateNonce(
 
243
    unsigned char** ospvNonceOut,
 
244
    unsigned*       ospvNonceLenOut,
 
245
    unsigned        ospvNonceLenIn
 
246
);
 
247
 
 
248
/*
 
249
 * Given a character string that will eventually be sent to an enrollment
 
250
 * server as part of a MsgInfo's Request, add a name-value pair that reflects
 
251
 * an enrollment parameter. 
 
252
 *
 
253
 * Input: the request's character string, plus the k
 
254
 *
 
255
 *
 
256
 */
 
257
int OSPPAddNameValuePair(
 
258
    unsigned char* ospvDestStr,
 
259
    unsigned char* ospvName,
 
260
    unsigned       ospvNameLen,
 
261
    unsigned char* ospvValue,
 
262
    unsigned       ospvValueLen,
 
263
    unsigned       ospvPrependAmpersand
 
264
);
 
265
 
 
266
/* Given a source string of characters, URL-encode it and append it to
 
267
 * the destination string:
 
268
 */
 
269
int OSPPAppendUrlEncodedString (
 
270
    unsigned char* destStr,
 
271
    unsigned char* srcStr,
 
272
    unsigned       srcStrLen
 
273
);
 
274
 
 
275
/*
 
276
 * Given a MessageInfo structure, extract the status from the "status=" field
 
277
 * that's contained in the Response field. If the status field cannot be found,
 
278
 * then this function will return an error.
 
279
 */
 
280
int OSPPGetStatusFromResponse (
 
281
    const OSPTMSGINFO* ospvMsgInfo,
 
282
    unsigned* ospvEnrollStatusOut
 
283
);
 
284
 
 
285
/*
 
286
 * Given a MessageInfo structure, extract the certificate from it. There
 
287
 * is no need to check the base64 encoding of the certificate or any other
 
288
 * structural constraints.
 
289
 */
 
290
int OSPPGetCertificateFromResponse (
 
291
    const OSPTMSGINFO* ospvMsgInfo,
 
292
    unsigned char*     ospvCertOut,
 
293
    unsigned*          ospvCertLenOut
 
294
);
 
295
 
 
296
/*
 
297
 * Given the CA certificate and a certificate that is supposedly for the
 
298
 * router, check its validity. That is, decode the base64 encoding of the
 
299
 * certificate, make sure that it's an X.509 cert, that it has the correct
 
300
 * version ( 2, to indicate a version 3 cert ); and that it's signed by
 
301
 * the CA. This should also include something for checking the public key
 
302
 * at some point.
 
303
 */
 
304
int OSPPValidateCert (
 
305
    const unsigned char* ospvCACertIn,
 
306
    const unsigned char* ospvCertIn,
 
307
    const unsigned ospvCertLenIn,
 
308
    const OSPTASN1OBJECT* ospvSubjectPublicKeyInfoIn,
 
309
    OSPTASN1OBJECT* ospvCertOut
 
310
);
 
311
 
 
312
/*
 
313
 * Compare the two ASN1 objects. Returns OSPC_ERR_NO_ERROR if they're the
 
314
 * same, and a non-zero value otherwise.
 
315
 *
 
316
 * Input:
 
317
 *   ospvLHSObject: a pointer to an ASN1 Object ( the LeftHand Side )
 
318
 *   ospvRHSObject: a pointer to an ASN1 Object ( the RightHand Side )
 
319
 *
 
320
 * Output:
 
321
 *   OSPC_ERR_NO_ERROR if the two are the same, or some other value otherwise.
 
322
 *
 
323
 * Errors: Errors will be returned when
 
324
 *   o at least one of the parameters is null ( OSPC_ERR_ENROLL_INVALID_PARAMS )
 
325
 *   o the two have different lengths ( OSPC_ERR_ENROLL_LENGTH_MISMATCH );
 
326
 *   o the two have different contents ( OSPC_ERR_ENROLL_CONTENT_MISMATCH );
 
327
 */
 
328
int OSPPASN1Compare (
 
329
    OSPTASN1OBJECT* ospvLHSObject,
 
330
    OSPTASN1OBJECT* ospvRHSObject
 
331
);
 
332
 
 
333
 
 
334
/*
 
335
 * This is for constructing the enrollment request that is sent to the 
 
336
 * enrollment server; the output is an OSPTMSGINFO structure that
 
337
 * contains it.
 
338
 *
 
339
 * Input: A pointer to the enrollment parameters and to the MessageInfo that
 
340
 *        contains the parameters for the enrollment request.
 
341
 *
 
342
 * Output: The OSPTMSGINFO should contain all of the information necessary
 
343
 *         for transmitting a request to the enrollment server. In this case,
 
344
 *         the return value will be OSPC_ERR_NO_ERROR. If something
 
345
 *         goes wrong, then the return value will be something other than
 
346
 *         OSPC_ERR_NO_ERROR. In that case, there is no guarantee about what
 
347
 *         the OSPTMSGINFO* structure will contain.
 
348
 */
 
349
int OSPPConstructEnrollmentRequest (
 
350
    OSPTENROLLPARAMS* ospvEnrollParamsIn,
 
351
    OSPTMSGINFO*      ospvMsgInfoOut
 
352
);
 
353
 
 
354
/* 
 
355
 * Given a base64 encoding of a certificate request, retrieve the 
 
356
 * subjectPublicKeyInfo from that certificate request and store it in the
 
357
 * given ASN.1 element info's placeholder. 
 
358
 *
 
359
 * Input: base64 certificate request 
 
360
 *        ( unsigned char* ospvBase64CertReq )
 
361
 *
 
362
 * Output: *ospvPublicKeyInfoOut should, if successful, contain the 
 
363
 *         subjectPublicKeyInfo of the certificate request. If not, then 
 
364
 *         an errorcode should be returned.
 
365
 *
 
366
 * Errors: Errorcodes other than OSPC_ERR_NO_ERROR are returned when:
 
367
 *     o either parameter is null;
 
368
 *     o memory cannot be allocated for ephemeral variables;
 
369
 *     o the certificate request is improperly base64 encoded;
 
370
 *     o the certificate request is invalid ( i.e., the subjectPublicKeyInfo
 
371
 *       could not be found in the desired location );
 
372
 */
 
373
int OSPPGetPublicKeyInfoFromCertReq( 
 
374
    unsigned char*   ospvBase64CertReq,
 
375
    OSPTASN1OBJECT*  ospvPublicKeyInfoOut 
 
376
);
 
377
 
 
378
/* Given a character string, make sure that it's valid: it's non-null,
 
379
 * and has nothing but ascii characters:
 
380
 */
 
381
int OSPPValidateAsciiString( 
 
382
    unsigned char* ospvAlnumStr 
 
383
);
 
384
 
 
385
/* Given a string of digits, make sure that it's valid: it's non-null,
 
386
 * and has nothing but digits.
 
387
 */
 
388
int OSPPValidateDigitString( 
 
389
    unsigned char* ospvDigitStr
 
390
); 
 
391
 
 
392
/* Given an ASN1 object that represents an X.509 certificate, store its
 
393
 * subjectPublicKeyInfo in the outbound ospvPublicKeyOut structure.
 
394
 * This subjectPublicKeyInfo will be compared against what we get from
 
395
 * the server in the form of a certificate; if they match, then the
 
396
 * certificate may be ok - otherwise, the certificate is bogus.
 
397
 *
 
398
 * Input: references to the input certificate and the outgoing 
 
399
 *        subjectPublicKeyInfo
 
400
 *
 
401
 * Output: If the subjectPublicKeyInfo can be found, then it should be
 
402
 *         stored in *ospvPublicKeyOut and the return value will be
 
403
 *         OSPC_ERR_NO_ERROR. Otherwise, the return value will be
 
404
 *         something other than OSPC_ERR_NO_ERROR.
 
405
 */
 
406
int OSPPGetPublicKeyInfoFromCert( 
 
407
    OSPTASN1OBJECT*  ospvCertIn, 
 
408
    OSPTASN1OBJECT*  ospvPublicKeyOut 
 
409
);
 
410
 
 
411
/* Given a binary string that represents a PKCS#10 request, create an
 
412
 * ASN1 object that contains the subjectPublicKeyInfo of the certificate
 
413
 * request. The subjectPublicKeyInfo is found as follows:
 
414
 *
 
415
 * SEQUENCE CertificateRequest        
 
416
 *     SEQUENCE certificateRequestInfo 
 
417
 *         INTEGER  version 
 
418
 *         SEQUENCE subjectName 
 
419
 *         SEQUENCE subjectPublicKeyInfo 
 
420
 *         SEQUENCE attributes
 
421
 *     OID signatureAlgorithm
 
422
 *     BIT STRING signature
 
423
 *
 
424
 * We'll use the ASN1 module from the OSP to decode the binary string
 
425
 * and extract the public key from the certificate request.
 
426
 *
 
427
 * Input: string representing a PKCS#10 certificate request, and a pointer
 
428
 *        to an ASN1 object for storing its subjectPublicKeyInfo.
 
429
 *
 
430
 * Output: the subjectPublicKeyInfo should be found, in which case we'll
 
431
 *         return OSPC_ERR_NO_ERROR. Otherwise, a different error code will
 
432
 *         be returned.
 
433
 */
 
434
int OSPPGetPublicKeyInfoFromCertReq(
 
435
    unsigned char*   ospvCertReqIn, 
 
436
    OSPTASN1OBJECT*  ospvPublicKeyOut 
 
437
); 
 
438
 
 
439
/* Cleanup the communications manager: its HTTP connections, security manager,
 
440
 * and the communications manager itself. The only way that this function
 
441
 * will return an error is if the communications manager passed in for deletion
 
442
 * is null.
 
443
 *
 
444
 * Input: reference to the communications manager pointer to be deleted.
 
445
 */
 
446
int OSPPEnrollCleanupCommMgr (
 
447
    OSPTCOMM** ospvCommMgrIn
 
448
);
 
449
 
 
450
#ifdef __cplusplus
 
451
}
 
452
#endif