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

« back to all changes in this revision

Viewing changes to src/osppkcs7.c

  • 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
/*
 
25
 * osppkcs7.c - PKCS #7 Cryptographic message object processing functions.
 
26
 */
 
27
 
 
28
#include "osp/osp.h"
 
29
#include "osp/ospasn1.h"
 
30
#include "osp/osppkcs1.h"
 
31
#include "osp/ospx509.h"
 
32
#include "osp/ospx500.h"
 
33
#include "osp/osppkcs1.h"
 
34
#include "osp/osppkcs7.h"
 
35
#include "osp/ospcrypto.h"
 
36
#include "osp/osptnlog.h"
 
37
#define DUMPOBJECTDATA(a, b)    { unsigned char *_data; unsigned int _dataLength; OSPTASN1ELEMENTINFO *_eInfo; OSPPASN1ObjectGetElementInfo(a, &_eInfo); OSPPASN1ElementGetElementData(_eInfo, &_data, &_dataLength); OSPTNLOGDUMP(_data, _dataLength, b); }
 
38
 
 
39
 
 
40
#define OSPC_ERR_PKCS7                              (25500)
 
41
#define OSPC_ERR_PKCS7_MALLOC_FAILED    (OSPC_ERR_PKCS7 + 1000)
 
42
 
 
43
 
 
44
/* FUNCTION PROTOTYPES */
 
45
 
 
46
/* ---------------------------------------------------------*/
 
47
/* Member functions                                         */
 
48
/* ---------------------------------------------------------*/
 
49
 
 
50
int
 
51
OSPPPKCS7SignatureCreate(
 
52
    unsigned char   *ospvContent,           /* In - data to signed */
 
53
    unsigned        ospvContentLength,      /* In - length of data to sign */
 
54
    OSPTASN1OBJECT  *ospvDigestAlgorithm,   /* In - ptr to digest Algorithm */
 
55
    OSPTASN1OBJECT  *ospvSignerCertInfo,    /* In - ptr to signer cert info */
 
56
    OSPTASN1OBJECT  *ospvSignerPrivateKey,  /* In - ptr to private key struct */
 
57
    int             ospvSignatureOnly,      /* In - TRUE - no content in sig
 
58
                                            FALSE- content included in sig */
 
59
    unsigned char   **ospvSignature,        /* Out - ptr to ptr to sig store */
 
60
    unsigned        *ospvSignatureLength)   /* Out - length of signature */
 
61
{
 
62
    int errorcode = OSPC_ERR_NO_ERROR;
 
63
 
 
64
    OSPTASN1OBJECT *signedData = OSPC_OSNULL;
 
65
    OSPTASN1OBJECT *contentInfo = OSPC_OSNULL;
 
66
    OSPTASN1OBJECT *dataContent = OSPC_OSNULL;
 
67
    OSPTASN1OBJECT *signerInfos = OSPC_OSNULL;
 
68
    OSPTASN1OBJECT *signerInfo = OSPC_OSNULL;
 
69
    OSPTASN1OBJECT *contentObject = OSPC_OSNULL;
 
70
    OSPTASN1OBJECT *certificates = OSPC_OSNULL;
 
71
    OSPTASN1OBJECT *digestAlgorithms = OSPC_OSNULL;
 
72
    OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL;
 
73
 
 
74
    /* Generate an ASN1 Encoded PKCS7 Signed Data signature from the
 
75
        parameters given.
 
76
 
 
77
        The signed data message is a Content info with a content type of 
 
78
        SIGNED DATA, and content, containing a Signed Data message which in
 
79
        turn contains a ContentInfo of type DATA.
 
80
    */
 
81
    /* Encode the content as and OctetString. */
 
82
    errorcode = OSPPASN1OctetStringEncode(&dataContent, ospvContent, 
 
83
        ospvContentLength, OSPEDRID_CNTINF_CONTENT);
 
84
 
 
85
    if (errorcode == OSPC_ERR_NO_ERROR)
 
86
    {
 
87
        /* Create the DATA content info structure for the content being
 
88
        signed.  Signature Only flag determines if the content is included
 
89
        or if an empty string is encoded in the ContentInfo. */
 
90
 
 
91
        errorcode = OSPPPKCS7ContentInfoCreate(&contentObject, dataContent, 
 
92
            OSPEID_DATA, ospvSignatureOnly);
 
93
    }
 
94
 
 
95
    if (errorcode == OSPC_ERR_NO_ERROR)
 
96
    {
 
97
        /* Generate the Set of Certificates */
 
98
        errorcode = OSPPPKCS7CertificatesCreate(&certificates,
 
99
            ospvSignerCertInfo);
 
100
    }   
 
101
 
 
102
    if (errorcode == OSPC_ERR_NO_ERROR)
 
103
    {
 
104
        /* Generate the set of DigestAlgorithms */
 
105
        errorcode = OSPPPKCS7DigestAlgorithmsCreate(&digestAlgorithms,
 
106
            ospvDigestAlgorithm);
 
107
    }   
 
108
 
 
109
 
 
110
    if (errorcode == OSPC_ERR_NO_ERROR)
 
111
    {
 
112
        /* Generate the Signer Info structure.  Generate a signature based
 
113
        on the content's octet string (content octets only, no tag or length */
 
114
        errorcode = OSPPPKCS7SignerInfoCreate(&signerInfo, dataContent,
 
115
            ospvDigestAlgorithm,
 
116
            ospvSignerCertInfo,
 
117
            ospvSignerPrivateKey);
 
118
    }   
 
119
 
 
120
    if (errorcode == OSPC_ERR_NO_ERROR)
 
121
    {
 
122
        /* Generate the Set of Signer Info structures. */ 
 
123
        errorcode = OSPPPKCS7SignerInfosCreate(&signerInfos,
 
124
            signerInfo);
 
125
    }   
 
126
 
 
127
    if (errorcode == OSPC_ERR_NO_ERROR)
 
128
    {
 
129
        /* First, create the signed data object using the function parameters.*/
 
130
        errorcode = OSPPPKCS7SignedDataCreate(&signedData, contentObject,
 
131
            digestAlgorithms, certificates,
 
132
            signerInfos);
 
133
    }
 
134
 
 
135
    if (errorcode == OSPC_ERR_NO_ERROR)
 
136
    {
 
137
        /* Next, create a ContentInfo with type SignedData. */
 
138
        errorcode = OSPPPKCS7ContentInfoCreate(&contentInfo,signedData,
 
139
            OSPEID_SIGNEDDATA, 0 );
 
140
    }
 
141
 
 
142
    if (errorcode == OSPC_ERR_NO_ERROR)
 
143
    {
 
144
        errorcode = OSPPASN1ObjectGetElementByDataRef(contentInfo, &eInfo, 
 
145
            OSPEDRID_CONTENTINFO);
 
146
 
 
147
        if (errorcode == OSPC_ERR_NO_ERROR)
 
148
        {
 
149
            errorcode = OSPPASN1ElementCopyElementData(eInfo,
 
150
                ospvSignature, ospvSignatureLength);
 
151
        }
 
152
    }
 
153
 
 
154
    OSPPASN1ObjectDelete(&certificates);
 
155
    OSPPASN1ObjectDelete(&digestAlgorithms);
 
156
    OSPPASN1ObjectDelete(&signerInfo);
 
157
    OSPPASN1ObjectDelete(&dataContent);
 
158
    OSPPASN1ObjectDelete(&signerInfos);
 
159
    OSPPASN1ObjectDelete(&signedData);
 
160
 
 
161
    OSPPASN1ObjectDelete(&contentInfo);
 
162
    OSPPASN1ElementDelete(&eInfo, 0);
 
163
    OSPPASN1ObjectDelete(&contentObject);
 
164
 
 
165
    return errorcode;
 
166
}
 
167
 
 
168
 
 
169
int 
 
170
OSPPPKCS7DigestInfoCreate(
 
171
    OSPTASN1OBJECT  **ospvDigestInfo,
 
172
    OSPTASN1OBJECT  *ospvDigestAlgorithm,
 
173
                                    unsigned char   *ospvContent,
 
174
    unsigned int    ospvContentLength)
 
175
{
 
176
    int errorcode = OSPC_ERR_NO_ERROR;
 
177
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
178
    OSPTASN1OBJECT *digestInfo = OSPC_OSNULL;
 
179
    OSPEASN1DATAREFID  dataRefId = OSPEDRID_NOTDEFINED;
 
180
 
 
181
    int i = 0;
 
182
 
 
183
 
 
184
    errorcode = OSPPASN1ObjectNew(&digestInfo, OSPEDRID_DIGESTINFO);
 
185
 
 
186
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
187
    {
 
188
        switch(i)
 
189
        {
 
190
            case 0: /* Add Digest Algorithm */
 
191
            dataRefId = OSPEDRID_DIGINF_DIGESTALGORITHM;
 
192
            errorcode = OSPPASN1ObjectCopy(&newObject,ospvDigestAlgorithm);
 
193
            if(newObject)   /* !!! PS */
 
194
            {
 
195
                OSPM_FREE(newObject->ElementInfo->Element);
 
196
                OSPM_FREE(newObject->ElementInfo);
 
197
            }
 
198
            break;
 
199
 
 
200
            case 1: /* Add Digest */
 
201
            dataRefId = OSPEDRID_DIGINF_DIGEST;
 
202
            if(newObject)   /* !!! PS */
 
203
            {
 
204
                OSPM_FREE(newObject->ElementInfo->Element);
 
205
                OSPM_FREE(newObject->ElementInfo);
 
206
            }
 
207
            errorcode = OSPPCryptoDigest( &newObject, ospvDigestAlgorithm,
 
208
                ospvContent, ospvContentLength);
 
209
 
 
210
            break;
 
211
 
 
212
            case 2:
 
213
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
214
            break;
 
215
 
 
216
            default:
 
217
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
218
            OSPM_DBGERRORLOG(errorcode, 
 
219
                "Unknown case encountered encoding PKCS7 DigestInfoCreate");
 
220
        }
 
221
 
 
222
        if (errorcode == OSPC_ERR_NO_ERROR)
 
223
        {
 
224
            /* Add new object to this object */
 
225
            if (newObject != OSPC_OSNULL)
 
226
            {
 
227
                errorcode = OSPPASN1ObjectAddChild( digestInfo, newObject,
 
228
                    dataRefId );
 
229
                OSPM_FREE(newObject);                                                       
 
230
                newObject = OSPC_OSNULL;
 
231
            }
 
232
        }
 
233
    }
 
234
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
235
    {
 
236
        errorcode = OSPC_ERR_NO_ERROR;
 
237
    }
 
238
 
 
239
    if (errorcode == OSPC_ERR_NO_ERROR)
 
240
    {
 
241
        /* Complete the encoding for this object. Update results, elements, 
 
242
            etc. */
 
243
        errorcode = OSPPASN1ObjectDeparse(digestInfo, OSPEPTID_DIGESTINFO,
 
244
            OSPEDRID_DIGESTINFO);
 
245
    }
 
246
 
 
247
    if (errorcode == OSPC_ERR_NO_ERROR) 
 
248
    {
 
249
        *ospvDigestInfo = digestInfo;
 
250
    }
 
251
    else
 
252
    {
 
253
        /* Clean up from errors */
 
254
        OSPPASN1ObjectDelete(&digestInfo);
 
255
    }
 
256
 
 
257
    return errorcode;
 
258
 
 
259
}
 
260
 
 
261
 
 
262
int 
 
263
OSPPPKCS7SignerInfoCreate(
 
264
OSPTASN1OBJECT      **ospvSignerInfo,
 
265
OSPTASN1OBJECT      *ospvDataContent,
 
266
OSPTASN1OBJECT      *ospvDigestAlgorithm,
 
267
OSPTASN1OBJECT      *ospvSignerCertInfo,
 
268
OSPTASN1OBJECT      *ospvSignerPrivateKey)
 
269
{
 
270
    int errorcode = OSPC_ERR_NO_ERROR;
 
271
 
 
272
    OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL;
 
273
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
274
    OSPTASN1OBJECT  *signerInfo = OSPC_OSNULL;
 
275
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
276
    OSPTASN1OBJECT *digestEncryptionAlgorithm = OSPC_OSNULL;
 
277
    OSPTASN1OBJECT *digestInfo = OSPC_OSNULL;
 
278
 
 
279
    unsigned char *contentData = OSPC_OSNULL;
 
280
    unsigned int  contentDataLength = 0;
 
281
 
 
282
    int i = 0;
 
283
 
 
284
    /*The Signature is a ContentInfo structure with a datatype of signedData
 
285
        */
 
286
 
 
287
    errorcode = OSPPASN1ObjectNew(&signerInfo, OSPEDRID_SIGNERINFO);
 
288
 
 
289
    /* The elements are a contentType OID, and a content element.  */
 
290
    /* Add the content type Element to the result list */
 
291
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
292
    {
 
293
        switch(i)
 
294
        {
 
295
            case 0: /* Add VERSION Element */
 
296
            dataRefId = OSPEDRID_SGNINF_VERSION;
 
297
            errorcode = OSPPASN1SmallIntegerEncode(&newObject, 
 
298
                OSPC_ASN1_SIGNERINFO_VERSION,
 
299
                dataRefId);
 
300
            break;
 
301
 
 
302
            case 1: /* Add Issuer */
 
303
            dataRefId = OSPEDRID_SGNINF_ISSUER;
 
304
            errorcode = OSPPASN1ObjectCopyElementObject(
 
305
                &newObject,
 
306
                ospvSignerCertInfo,
 
307
                OSPEDRID_CERT_ISSUER);
 
308
            if(newObject != OSPC_OSNULL)
 
309
            {
 
310
                if(newObject->ElementInfo != OSPC_OSNULL)
 
311
                {
 
312
                    OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
 
313
                }
 
314
            }
 
315
            break;
 
316
 
 
317
            case 2: /* Add SerialNumber */
 
318
            dataRefId = OSPEDRID_SGNINF_SERIALNUMBER;
 
319
            errorcode = OSPPASN1ObjectCopyElementObject(&newObject, 
 
320
                ospvSignerCertInfo, 
 
321
                OSPEDRID_CERT_SERIALNUMBER);
 
322
            if(newObject != OSPC_OSNULL)
 
323
            {
 
324
                if(newObject->ElementInfo != OSPC_OSNULL)
 
325
                {
 
326
                    OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
 
327
                }
 
328
            }
 
329
            break;
 
330
 
 
331
            case 3: /* Add DigestAlgorithm */
 
332
            dataRefId = OSPEDRID_SGNINF_DIGESTALGORITHM;
 
333
            errorcode = OSPPASN1ObjectCopy(&newObject, 
 
334
                ospvDigestAlgorithm);
 
335
            if(newObject != OSPC_OSNULL)
 
336
            {
 
337
                if(newObject->ElementInfo != OSPC_OSNULL)
 
338
                {
 
339
                    OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
 
340
                }
 
341
            }
 
342
            break;
 
343
 
 
344
            case 4: /* Add AuthenticatedAttributes */
 
345
            dataRefId = OSPEDRID_SGNINF_AUTHATTRIBUTES;
 
346
            break;
 
347
 
 
348
            case 5: /* Add DigestEncryptionAlgorithm */
 
349
            dataRefId = OSPEDRID_SGNINF_DIGENCRYPTALG;
 
350
            errorcode = OSPPASN1ObjectCopyElementObject(&newObject, 
 
351
                ospvSignerCertInfo, 
 
352
                OSPEDRID_CERT_PUBLICKEYALG);
 
353
            if(newObject != OSPC_OSNULL)
 
354
            {
 
355
                if(newObject->ElementInfo != OSPC_OSNULL)
 
356
                {
 
357
                    OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
 
358
                }
 
359
            }
 
360
            break;
 
361
 
 
362
            case 6: /* Add EncryptedDigest */
 
363
            dataRefId = OSPEDRID_SGNINF_ENCRYPTEDDIGEST;
 
364
            errorcode = OSPPASN1ObjectGetElementInfo(ospvDataContent,
 
365
                &eInfo);
 
366
 
 
367
 
 
368
            if (errorcode == OSPC_ERR_NO_ERROR)
 
369
            {
 
370
                errorcode = OSPPASN1ElementGetContentData(eInfo,
 
371
                    &contentData, &contentDataLength);
 
372
            }
 
373
 
 
374
 
 
375
            if (errorcode == OSPC_ERR_NO_ERROR)
 
376
            {
 
377
                errorcode = OSPPPKCS7DigestInfoCreate(&digestInfo,
 
378
                    ospvDigestAlgorithm,
 
379
                    contentData, contentDataLength);
 
380
            }
 
381
 
 
382
            if (errorcode == OSPC_ERR_NO_ERROR)
 
383
            {
 
384
                errorcode = OSPPASN1ObjectCopyElementObject(
 
385
                    &digestEncryptionAlgorithm, 
 
386
                    ospvSignerCertInfo, 
 
387
                    OSPEDRID_CERT_PUBLICKEYALG);
 
388
            }
 
389
/*
 
390
            if (errorcode == OSPC_ERR_NO_ERROR)
 
391
            {
 
392
                unsigned char *pubkeybuf = OSPC_OSNULL;
 
393
                unsigned int pubkeybuflen = 0;
 
394
                OSPTASN1ELEMENTINFO *tmpSignerSubjPubKeyInfo = OSPC_OSNULL;
 
395
 
 
396
                errorcode = OSPPASN1ObjectGetElementByDataRef(
 
397
                    ospvSignerCertInfo, &tmpSignerSubjPubKeyInfo,
 
398
                    OSPEDRID_CERT_SUBJPUBKEYINFO);
 
399
 
 
400
                errorcode = OSPPASN1ElementGetElementData(
 
401
                    tmpSignerSubjPubKeyInfo, &pubkeybuf, &pubkeybuflen);
 
402
 
 
403
                OSPTNLOGDUMP(pubkeybuf, pubkeybuflen,"signer PUB KEY INFO");
 
404
            }
 
405
*/
 
406
            if (errorcode == OSPC_ERR_NO_ERROR)
 
407
            {
 
408
                errorcode = OSPPCryptoEncrypt(&newObject,
 
409
                    digestEncryptionAlgorithm,
 
410
                    digestInfo,
 
411
                    ospvSignerPrivateKey);
 
412
            }
 
413
            if(digestInfo != OSPC_OSNULL)
 
414
            {
 
415
                OSPPASN1ObjectDelete(&digestInfo);
 
416
            }
 
417
 
 
418
            if(digestEncryptionAlgorithm != OSPC_OSNULL)
 
419
            {
 
420
                OSPPASN1ElementDelete(&(digestEncryptionAlgorithm->ParseResults->ElementInfo), 0);
 
421
                OSPPASN1ObjectDelete(&digestEncryptionAlgorithm);
 
422
            }
 
423
            break;
 
424
 
 
425
            case 7: /* Add UnAuthenticatedAttributes */
 
426
            dataRefId = OSPEDRID_SGNINF_UNAUTHATTRIBUTES;
 
427
            newObject = OSPC_OSNULL;        /* Add nothing */
 
428
            break;
 
429
 
 
430
            case 8:
 
431
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
432
            break;
 
433
 
 
434
            default:
 
435
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
436
            OSPM_DBGERRORLOG(errorcode, 
 
437
                "Unknown case encountered encoding PKCS7 SignerInfo");
 
438
        }
 
439
 
 
440
        if (errorcode == OSPC_ERR_NO_ERROR)
 
441
        {
 
442
            /* Add new object to this object */
 
443
            if (newObject != OSPC_OSNULL)
 
444
            {
 
445
                errorcode = OSPPASN1ObjectAddChild(signerInfo, newObject,
 
446
                    dataRefId);
 
447
                if(newObject != OSPC_OSNULL)
 
448
                {
 
449
                    OSPM_FREE(newObject);
 
450
                }
 
451
            }
 
452
        }
 
453
    }
 
454
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
455
    {
 
456
        errorcode = OSPC_ERR_NO_ERROR;
 
457
    }
 
458
 
 
459
    if (errorcode == OSPC_ERR_NO_ERROR)
 
460
    {
 
461
        /* Complete the encoding for this object. Update results, elements, 
 
462
            etc. */
 
463
        errorcode = OSPPASN1ObjectDeparse(signerInfo, 
 
464
            OSPEPTID_SIGNERINFO,
 
465
            OSPEDRID_SIGNERINFO);
 
466
    }
 
467
 
 
468
 
 
469
    if (errorcode == OSPC_ERR_NO_ERROR)
 
470
    {
 
471
        *ospvSignerInfo = signerInfo;
 
472
    }
 
473
    else
 
474
    {
 
475
        /* Clean up from errors */
 
476
        OSPPASN1ObjectDelete(&signerInfo);
 
477
    }
 
478
 
 
479
    if(digestInfo != OSPC_OSNULL)
 
480
    {
 
481
        OSPM_FREE(digestInfo);
 
482
    }
 
483
 
 
484
    return errorcode;
 
485
}
 
486
 
 
487
int
 
488
OSPPPKCS7DigestAlgorithmsCreate(
 
489
OSPTASN1OBJECT      **ospvDigestAlgorithms,
 
490
OSPTASN1OBJECT      *ospvDigestAlgorithm)
 
491
{
 
492
    int errorcode=OSPC_ERR_NO_ERROR;
 
493
 
 
494
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
495
    OSPTASN1OBJECT  *digestAlgorithms = OSPC_OSNULL;
 
496
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
497
 
 
498
    int i = 0;
 
499
 
 
500
    errorcode = OSPPASN1ObjectNew(&digestAlgorithms, 
 
501
        OSPEDRID_SGNDAT_DIGESTALGORITHMS);
 
502
 
 
503
    /* The elements are a contentType OID, and a content element.  */
 
504
    /* Add the content type Element to the result list */
 
505
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
506
    {
 
507
        switch(i)
 
508
        {
 
509
            case 0: /* Add DigestAlgorithm */
 
510
            dataRefId = OSPEDRID_SGNDAT_DIGESTALGORITHM;
 
511
            errorcode = OSPPASN1ObjectCopy(&newObject, ospvDigestAlgorithm);
 
512
            if(newObject != OSPC_OSNULL)
 
513
            {
 
514
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
515
            }
 
516
            break;
 
517
 
 
518
            case 1:
 
519
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
520
            break;
 
521
 
 
522
            default:
 
523
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
524
            OSPM_DBGERRORLOG(errorcode, 
 
525
                "Unknown case encountered encoding PKCS7 DigestAlgorithms");
 
526
        }
 
527
 
 
528
        if (errorcode == OSPC_ERR_NO_ERROR)
 
529
        {
 
530
            /* Add new object to this object */
 
531
            if (newObject != OSPC_OSNULL)
 
532
            {
 
533
                errorcode = OSPPASN1ObjectAddChild(digestAlgorithms, newObject,
 
534
                    dataRefId);
 
535
                OSPM_FREE(newObject);
 
536
            }
 
537
        }
 
538
    }
 
539
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
540
    {
 
541
        errorcode = OSPC_ERR_NO_ERROR;
 
542
    }
 
543
 
 
544
    if (errorcode == OSPC_ERR_NO_ERROR)
 
545
    {
 
546
        /* Complete the encoding for this object. Update results, elements, 
 
547
            etc. */
 
548
        errorcode = OSPPASN1ObjectDeparse(digestAlgorithms, 
 
549
            OSPEPTID_DIGESTALGORITHMS,
 
550
            OSPEDRID_SGNDAT_DIGESTALGORITHMS);
 
551
    }
 
552
 
 
553
    if (errorcode == OSPC_ERR_NO_ERROR)
 
554
    {
 
555
        *ospvDigestAlgorithms = digestAlgorithms;
 
556
    }
 
557
    else
 
558
    {
 
559
        /* Clean up from errors */
 
560
        OSPPASN1ObjectDelete(&digestAlgorithms);
 
561
    }
 
562
 
 
563
    return errorcode;
 
564
}
 
565
 
 
566
 
 
567
int
 
568
OSPPPKCS7CertificatesCreate(
 
569
    OSPTASN1OBJECT      **ospvCertificates,
 
570
    OSPTASN1OBJECT      *ospvCertificate)
 
571
{
 
572
    int errorcode = OSPC_ERR_NO_ERROR;
 
573
 
 
574
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
575
    OSPTASN1OBJECT  *certificates = OSPC_OSNULL;
 
576
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
577
 
 
578
    int i = 0;
 
579
 
 
580
    errorcode = OSPPASN1ObjectNew(&certificates, 
 
581
        OSPEDRID_SGNDAT_CERTIFICATES);
 
582
 
 
583
    /* The elements are a contentType OID, and a content element.  */
 
584
    /* Add the content type Element to the result list */
 
585
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
586
    {
 
587
        switch(i)
 
588
        {
 
589
            case 0: /* Add Certificate */
 
590
            dataRefId = OSPEDRID_SGNDAT_CERTIFICATE;
 
591
            errorcode = OSPPASN1ObjectCopy(&newObject, ospvCertificate);
 
592
            if(newObject->ElementInfo->Element != OSPC_OSNULL)
 
593
            {
 
594
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
595
            }
 
596
            break;
 
597
 
 
598
            case 1:
 
599
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
600
            break;
 
601
 
 
602
            default:
 
603
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
604
            OSPM_DBGERRORLOG(errorcode, 
 
605
                "Unknown case encountered encoding PKCS7 Certificates");
 
606
        }
 
607
 
 
608
        if (errorcode == OSPC_ERR_NO_ERROR)
 
609
        {
 
610
            /* Add new object to this object */
 
611
            if (newObject != OSPC_OSNULL)
 
612
            {
 
613
                errorcode = OSPPASN1ObjectAddChild(certificates, newObject,
 
614
                    dataRefId);
 
615
                OSPM_FREE(newObject);
 
616
            }
 
617
        }
 
618
    }
 
619
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
620
    {
 
621
        errorcode = OSPC_ERR_NO_ERROR;
 
622
    }
 
623
 
 
624
    if (errorcode == OSPC_ERR_NO_ERROR)
 
625
    {
 
626
        /* Complete the encoding for this object. Update results, elements, 
 
627
            etc. */
 
628
        errorcode = OSPPASN1ObjectDeparse(certificates, 
 
629
            OSPEPTID_CERTIFICATES,
 
630
            OSPEDRID_SGNDAT_CERTIFICATES);
 
631
    }
 
632
 
 
633
    if (errorcode == OSPC_ERR_NO_ERROR)
 
634
    {
 
635
        *ospvCertificates = certificates;
 
636
    }
 
637
    else
 
638
    {
 
639
        /* Clean up from errors */
 
640
        OSPPASN1ObjectDelete(&certificates);
 
641
    }
 
642
 
 
643
    return errorcode;
 
644
}
 
645
 
 
646
 
 
647
int
 
648
OSPPPKCS7SignerInfosCreate(
 
649
    OSPTASN1OBJECT      **ospvSignerInfos,
 
650
    OSPTASN1OBJECT      *ospvSignerInfo)
 
651
{
 
652
    int errorcode = OSPC_ERR_NO_ERROR;
 
653
 
 
654
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
655
    OSPTASN1OBJECT  *signerInfos = OSPC_OSNULL;
 
656
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
657
 
 
658
    int i = 0;
 
659
 
 
660
    errorcode = OSPPASN1ObjectNew(&signerInfos, OSPEDRID_SGNDAT_SIGNERINFOS);
 
661
 
 
662
    /* The elements are a contentType OID, and a content element.  */
 
663
    /* Add the content type Element to the result list */
 
664
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
665
    {
 
666
        switch(i)
 
667
        {
 
668
            case 0: /* Add SignerInfo */
 
669
            dataRefId = OSPEDRID_SGNDAT_SIGNERINFO;
 
670
            errorcode = OSPPASN1ObjectCopy(&newObject, ospvSignerInfo);
 
671
            if(newObject->ElementInfo->Element != OSPC_OSNULL)
 
672
            {
 
673
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
674
            }
 
675
            break;
 
676
 
 
677
            case 1:
 
678
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
679
            break;
 
680
 
 
681
            default:
 
682
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
683
            OSPM_DBGERRORLOG(errorcode, 
 
684
                "Unknown case encountered encoding PKCS7 SignerInfos");
 
685
        }
 
686
 
 
687
        if (errorcode == OSPC_ERR_NO_ERROR)
 
688
        {
 
689
            /* Add new object to this object */
 
690
            if (newObject != OSPC_OSNULL)
 
691
            {
 
692
                errorcode = OSPPASN1ObjectAddChild(signerInfos, newObject,
 
693
                    dataRefId);
 
694
                if(newObject != OSPC_OSNULL)
 
695
                {
 
696
                    OSPM_FREE(newObject);
 
697
                }
 
698
            }
 
699
        }
 
700
    }
 
701
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
702
    {
 
703
        errorcode = OSPC_ERR_NO_ERROR;
 
704
    }
 
705
 
 
706
    if (errorcode == OSPC_ERR_NO_ERROR)
 
707
    {
 
708
        /* Complete the encoding for this object. Update results, elements, 
 
709
            etc. */
 
710
        errorcode = OSPPASN1ObjectDeparse(signerInfos, 
 
711
            OSPEPTID_SIGNERINFOS,
 
712
            OSPEDRID_SGNDAT_SIGNERINFOS);
 
713
    }
 
714
 
 
715
    if (errorcode == OSPC_ERR_NO_ERROR)
 
716
    {
 
717
        *ospvSignerInfos = signerInfos;
 
718
    }
 
719
    else
 
720
    {
 
721
        /* Clean up from errors */
 
722
        OSPPASN1ObjectDelete(&signerInfos);
 
723
    }
 
724
 
 
725
    return errorcode;
 
726
}
 
727
 
 
728
 
 
729
int
 
730
OSPPPKCS7SignedDataCreate(
 
731
    OSPTASN1OBJECT  **ospvSignedData,
 
732
    OSPTASN1OBJECT  *ospvContentInfo,   
 
733
    OSPTASN1OBJECT  *ospvDigestAlgorithms,
 
734
    OSPTASN1OBJECT  *ospvSignerCertificates, 
 
735
    OSPTASN1OBJECT  *ospvSignerInfos)
 
736
{
 
737
    int errorcode = OSPC_ERR_NO_ERROR;
 
738
    unsigned int i = 0;
 
739
 
 
740
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
741
 
 
742
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
743
    OSPTASN1OBJECT *signedData = OSPC_OSNULL;
 
744
 
 
745
    errorcode = OSPPASN1ObjectNew(&signedData, OSPEDRID_SIGNEDDATA);
 
746
 
 
747
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
748
    {
 
749
        switch(i)
 
750
        {
 
751
            case 0:
 
752
            dataRefId = OSPEDRID_SGNDAT_VERSION;
 
753
            errorcode = OSPPASN1SmallIntegerEncode(&newObject, 
 
754
                OSPC_PKCS7_SIGNEDDATA_VERSION,
 
755
                dataRefId);
 
756
            break;
 
757
 
 
758
            case 1:
 
759
            dataRefId = OSPEDRID_SGNDAT_DIGESTALGORITHMS;
 
760
            errorcode = OSPPASN1ObjectCopy(&newObject, 
 
761
                ospvDigestAlgorithms);
 
762
            if(newObject != OSPC_OSNULL)
 
763
            {
 
764
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
765
            }
 
766
            break;
 
767
 
 
768
            case 2:
 
769
            dataRefId = OSPEDRID_SGNDAT_CONTENTINFO;
 
770
            errorcode = OSPPASN1ObjectCopy(&newObject, 
 
771
                ospvContentInfo);
 
772
            if(newObject != OSPC_OSNULL)
 
773
            {
 
774
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
775
            }
 
776
            break;
 
777
 
 
778
            case 3:
 
779
            dataRefId = OSPEDRID_SGNDAT_CERTIFICATES;
 
780
            errorcode = OSPPASN1ObjectCopy(&newObject, 
 
781
                ospvSignerCertificates);
 
782
            if(newObject != OSPC_OSNULL)
 
783
            {
 
784
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
785
            }
 
786
            break;
 
787
 
 
788
            case 4:
 
789
            dataRefId = OSPEDRID_SGNDAT_SIGNERINFOS;
 
790
            errorcode = OSPPASN1ObjectCopy(&newObject, 
 
791
                ospvSignerInfos);
 
792
            if(newObject != OSPC_OSNULL)
 
793
            {
 
794
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);               
 
795
            }
 
796
            break;
 
797
 
 
798
            case 5:
 
799
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
800
            break;
 
801
 
 
802
            default:
 
803
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
804
            OSPM_DBGERRORLOG(errorcode, 
 
805
                "Unknown case encountered encoding PKCS7 SignedData");
 
806
        }
 
807
 
 
808
        if (errorcode == OSPC_ERR_NO_ERROR)
 
809
        {
 
810
            /* Add new object to this object */
 
811
            if (newObject != OSPC_OSNULL)
 
812
            {
 
813
                errorcode = OSPPASN1ObjectAddChild(signedData, newObject,
 
814
                    dataRefId);
 
815
                OSPM_FREE(newObject);
 
816
            }
 
817
        }
 
818
    }
 
819
 
 
820
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
821
    {
 
822
        errorcode = OSPC_ERR_NO_ERROR;
 
823
    }
 
824
 
 
825
    if (errorcode == OSPC_ERR_NO_ERROR)
 
826
    {
 
827
        errorcode = OSPPASN1ObjectDeparse(signedData, 
 
828
            OSPEPTID_SIGNEDDATA,
 
829
            OSPEDRID_SIGNEDDATA);
 
830
    }
 
831
    if (errorcode == OSPC_ERR_NO_ERROR)
 
832
    {
 
833
        *ospvSignedData = signedData;
 
834
    }
 
835
 
 
836
    else
 
837
    {
 
838
        /* Clean up from errors */
 
839
        OSPPASN1ObjectDelete(&signedData);
 
840
    }    
 
841
    
 
842
    if(newObject != OSPC_OSNULL)
 
843
    {
 
844
        OSPPASN1ObjectDelete(&newObject);
 
845
    }
 
846
 
 
847
    return errorcode;
 
848
}      
 
849
 
 
850
 
 
851
 
 
852
int
 
853
OSPPPKCS7ContentInfoCreate( 
 
854
    OSPTASN1OBJECT **ospvContentInfo,
 
855
    OSPTASN1OBJECT *ospvContent,
 
856
    OSPEASN1ID ospvContentTypeId, 
 
857
    int ospvSignatureOnly)
 
858
{
 
859
    int errorcode = 0;
 
860
    unsigned int           i     = 0;
 
861
 
 
862
    OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
 
863
    OSPEASN1PARSETABLEID tableId = OSPEPTID_NOTDEFINED;
 
864
 
 
865
    OSPTASN1OBJECT *newObject = OSPC_OSNULL;
 
866
    OSPTASN1OBJECT *contentInfo = OSPC_OSNULL;
 
867
 
 
868
    /*The Signature is a ContentInfo sturcture with a datatype of signedData
 
869
    */
 
870
 
 
871
    /* Create a parse result for each of the input parameters.  Add the
 
872
    result to the results list in the correct order.  It will be necessary 
 
873
    to call subroutines to build the sub element.  The parse results table will
 
874
    have DataReference-able elements attached.  Running the parse table
 
875
    through the rules to build the element info list and then traversing
 
876
    the element info list should build an ASN1 encode object.  */
 
877
 
 
878
    /* Signed Data structure will contain element info pointer (null), and
 
879
    a parse results table containing populated data elements with data
 
880
    reference values. */
 
881
 
 
882
    /* Content type is SignedData.  Content may or may not be contained in
 
883
    the signed data structure.  */
 
884
 
 
885
    /* Create a content info object for the signature */
 
886
    errorcode = OSPPASN1ObjectNew(&contentInfo, OSPEDRID_CONTENTINFO);
 
887
 
 
888
    /* The elements are a contentType OID, and a content element.  */
 
889
    /* Add the content type Element to the result list */
 
890
    for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
 
891
    {
 
892
        switch(i)
 
893
        {
 
894
            case 0:
 
895
            dataRefId = OSPEDRID_CNTINF_CONTENTTYPE;
 
896
            errorcode = OSPPASN1ObjectIdentifierEncode(&newObject, 
 
897
                ospvContentTypeId,
 
898
                dataRefId);
 
899
            break;
 
900
 
 
901
            case 1:
 
902
            dataRefId = OSPEDRID_CNTINF_CONTENT;           
 
903
            if ((ospvSignatureOnly) && (newObject != OSPC_OSNULL))
 
904
            {
 
905
                OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
 
906
            }
 
907
            else
 
908
            {
 
909
                errorcode = OSPPASN1ObjectCopy(&newObject,ospvContent);
 
910
                if(newObject != OSPC_OSNULL)
 
911
                {
 
912
                    OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);            
 
913
                }
 
914
            }
 
915
            break;
 
916
 
 
917
            case 2:
 
918
            errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
 
919
            break;
 
920
 
 
921
            default:
 
922
            errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
 
923
            OSPM_DBGERRORLOG(errorcode, 
 
924
                "Unknown case encountered encoding PKCS7 ContentInfo.");
 
925
        }
 
926
 
 
927
        if (errorcode == OSPC_ERR_NO_ERROR)
 
928
        {
 
929
            /* Add new object to this object */
 
930
            if (newObject != OSPC_OSNULL)
 
931
            {
 
932
                errorcode = OSPPASN1ObjectAddChild(contentInfo, newObject,
 
933
                    dataRefId);
 
934
                OSPM_FREE(newObject);
 
935
            }
 
936
        }   
 
937
    }
 
938
 
 
939
    if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
 
940
    {
 
941
        errorcode = OSPC_ERR_NO_ERROR;
 
942
    }
 
943
 
 
944
    if (errorcode == OSPC_ERR_NO_ERROR)
 
945
    {
 
946
        if (ospvContentTypeId == OSPEID_DATA)
 
947
        {
 
948
            tableId = OSPEPTID_CONTENTINFO_DATA; 
 
949
        }
 
950
        else if (ospvContentTypeId == OSPEID_SIGNEDDATA)
 
951
        {
 
952
            tableId = OSPEPTID_CONTENTINFO_SIGNEDDATA;
 
953
        }
 
954
        else
 
955
        {
 
956
            errorcode = OSPC_ERR_ASN1_PARSE_ERROR;
 
957
            OSPM_DBGERRORLOG(errorcode, 
 
958
                "Unsupported contentInfo type specified");
 
959
        }
 
960
 
 
961
        if (errorcode == OSPC_ERR_NO_ERROR)
 
962
        {
 
963
            errorcode = OSPPASN1ObjectDeparse(contentInfo, tableId,
 
964
                OSPEDRID_CONTENTINFO);
 
965
        }
 
966
    }   
 
967
 
 
968
    if (errorcode == OSPC_ERR_NO_ERROR)
 
969
    {
 
970
        *ospvContentInfo = contentInfo;
 
971
    }
 
972
    else
 
973
    {
 
974
        OSPPASN1ObjectDelete(&contentInfo);
 
975
        /* Do the cleanup stuff here */ 
 
976
    }
 
977
 
 
978
    if(newObject != OSPC_OSNULL)
 
979
    {
 
980
        OSPPASN1ObjectDelete(&newObject);
 
981
    }
 
982
 
 
983
    return errorcode;
 
984
}
 
985
 
 
986
 
 
987
/* Caller must provide space for content.  ospvContentLength should be set
 
988
to the size of the space provided.  An error will occur if the content
 
989
contained in the signature is larger than the space provided.
 
990
 
 
991
If the signature does not contain the signed content, then the caller will
 
992
set content to the data that was signed and set content length to the
 
993
length of the data being signed.  
 
994
 
 
995
If the signature does contain the signed content, then the call should set
 
996
content to zeros and set contentlength to the size of the content buffer.
 
997
The content from the signature will be copied to the content buffer and the
 
998
length will be changed to the actual length of the content.  An error will
 
999
occur if the length of the content is larger than the length of the buffer.
 
1000
*/
 
1001
 
 
1002
int
 
1003
OSPPPKCS7SignatureParse(
 
1004
    OSPTASN1OBJECT **ospvSignatureObject,
 
1005
    unsigned char *ospvSignature,
 
1006
    unsigned int  ospvSignatureLength)
 
1007
{
 
1008
    int errorcode = OSPC_ERR_NO_ERROR;
 
1009
    OSPTASN1OBJECT *signatureObject = OSPC_OSNULL;
 
1010
    OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL;
 
1011
    OSPTASN1PARSERESULT *parseResults = OSPC_OSNULL;
 
1012
 
 
1013
    if ((ospvSignatureObject == OSPC_OSNULL) ||
 
1014
        (ospvSignature == OSPC_OSNULL) ||
 
1015
        (ospvSignatureLength == 0))
 
1016
    {
 
1017
        errorcode = OSPC_ERR_PKCS7_INVALID_POINTER;
 
1018
        OSPM_DBGERRORLOG(errorcode, "Invalid input or output pointers");
 
1019
    }
 
1020
 
 
1021
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1022
    {
 
1023
        /* Decode the signature into element and build element list */
 
1024
        errorcode = OSPPASN1ElementDecode(ospvSignature, &eInfo, 0);
 
1025
    }
 
1026
 
 
1027
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1028
    {
 
1029
        /* Parse the element list to validate structure and get cross
 
1030
        reference list elements */
 
1031
        errorcode = OSPPASN1ElementParse( eInfo, 
 
1032
            OSPEPTID_CONTENTINFO_SIGNEDDATA, 
 
1033
            OSPC_OSNULL,
 
1034
            &parseResults, 
 
1035
            OSPC_ASN1_DATAREFID_CONTENTINFO);
 
1036
    }
 
1037
 
 
1038
 
 
1039
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1040
    {
 
1041
        /* Create the signatureObject object that will contain the 
 
1042
            decoded/parsed signature */
 
1043
        errorcode = OSPPASN1ObjectCreate(&signatureObject, eInfo, parseResults);
 
1044
    }
 
1045
 
 
1046
 
 
1047
 
 
1048
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1049
    {
 
1050
        *ospvSignatureObject = signatureObject;
 
1051
 
 
1052
    }
 
1053
 
 
1054
    return errorcode;
 
1055
}   
 
1056
 
 
1057
 
 
1058
int
 
1059
OSPPPKCS7SignatureGetContent(
 
1060
    OSPTASN1OBJECT *ospvSignatureObject,
 
1061
    unsigned char **ospvContent, 
 
1062
    unsigned int  *ospvContentLength,
 
1063
    OSPTASN1ELEMENTINFO **el    )
 
1064
{
 
1065
    int errorcode = OSPC_ERR_NO_ERROR;
 
1066
    OSPTASN1ELEMENTINFO *contentElement = OSPC_OSNULL;
 
1067
    unsigned char *content = OSPC_OSNULL;
 
1068
    unsigned int  contentLength = 0;
 
1069
 
 
1070
    /* Extract content from signature object */
 
1071
    errorcode = OSPPASN1ObjectGetElementByDataRef(
 
1072
        ospvSignatureObject, &contentElement,
 
1073
        OSPEDRID_SIG_SGNDAT_DATA);
 
1074
 
 
1075
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1076
    {
 
1077
        /* Now we have the data element that should contain the data that
 
1078
        was signed. */
 
1079
 
 
1080
        /* Get pointer to data and set length */
 
1081
        errorcode = OSPPASN1ElementGetContentData(contentElement, 
 
1082
            &content, &contentLength);
 
1083
 
 
1084
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1085
        {
 
1086
            *ospvContent = content;
 
1087
            *ospvContentLength = contentLength;
 
1088
 
 
1089
        }
 
1090
        if(OSPC_OSNULL!=el) /* !!! PS */
 
1091
        {
 
1092
            *el=contentElement;
 
1093
        }
 
1094
    }
 
1095
    return errorcode;
 
1096
}
 
1097
 
 
1098
 
 
1099
int
 
1100
OSPPPKCS7SignatureVerify(
 
1101
    OSPTASN1OBJECT *ospvSignatureObject,
 
1102
    unsigned char  *ospvContent, 
 
1103
    unsigned int   ospvContentLength,
 
1104
    OSPTASN1OBJECT *ospvAuthorityCertificates[],
 
1105
    unsigned int   ospvNumberOfAuthorityCertificates)
 
1106
{
 
1107
    int errorcode = OSPC_ERR_NO_ERROR;
 
1108
    OSPTASN1OBJECT *digestAlgorithmId = OSPC_OSNULL;
 
1109
    OSPTASN1OBJECT *encryptionAlgorithm = OSPC_OSNULL;
 
1110
    OSPTASN1OBJECT *encryptedDigest = OSPC_OSNULL;
 
1111
    OSPTASN1OBJECT *subjPubKeyInfo = OSPC_OSNULL;
 
1112
    OSPTASN1OBJECT *signerCertificate = OSPC_OSNULL;
 
1113
    OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL;
 
1114
    unsigned char *contentDigest = OSPC_OSNULL;
 
1115
    unsigned int  contentDigestLength = 0;
 
1116
    OSPTASN1OBJECT *decryptedDigestObject = OSPC_OSNULL;
 
1117
    OSPTASN1OBJECT *digestInfo = OSPC_OSNULL;
 
1118
    unsigned char *decryptedDigest = OSPC_OSNULL;
 
1119
    unsigned int  decryptedDigestLength = 0;
 
1120
 
 
1121
    if ((ospvContent == OSPC_OSNULL) || (ospvContentLength == 0))
 
1122
    {
 
1123
        errorcode = OSPC_ERR_PKCS7_INVALID_POINTER;
 
1124
        OSPM_DBGERRORLOG(errorcode, 
 
1125
            "Content buffer pointer is null, or length is 0");
 
1126
    }
 
1127
 
 
1128
 
 
1129
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1130
    {
 
1131
        /* Now we have the content that was signed and the length.
 
1132
        Need to generate a digest of it for comparison against the
 
1133
        signature */
 
1134
 
 
1135
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1136
        {
 
1137
 
 
1138
            /* Get the digest algorithm id from the signature object. */
 
1139
            errorcode = OSPPASN1ObjectCopyElementObject( &digestAlgorithmId,
 
1140
                ospvSignatureObject, 
 
1141
                OSPEDRID_SIG_SGNDAT_SGNINF_DIGESTALGORITHM);
 
1142
        }
 
1143
 
 
1144
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1145
        {
 
1146
            /* Create a local Digest Info object to compare to results of
 
1147
            decryption. */
 
1148
            errorcode = OSPPPKCS7DigestInfoCreate(&digestInfo, 
 
1149
                digestAlgorithmId,
 
1150
                ospvContent, ospvContentLength);
 
1151
 
 
1152
            if (errorcode == OSPC_ERR_NO_ERROR)
 
1153
            {
 
1154
                errorcode = OSPPASN1ObjectGetElementInfo(digestInfo, &eInfo);
 
1155
                if (errorcode == OSPC_ERR_NO_ERROR)
 
1156
                {
 
1157
                    errorcode = OSPPASN1ElementGetElementData(eInfo,
 
1158
                        &contentDigest, &contentDigestLength);
 
1159
                }
 
1160
            }
 
1161
        }
 
1162
 
 
1163
    }
 
1164
 
 
1165
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1166
    {
 
1167
        /* Ok, now we have a digest of the content, Decrypt the
 
1168
        signature to get the digest that was encrypted and compare the 
 
1169
        two digests */ 
 
1170
 
 
1171
        errorcode = OSPPASN1ObjectCopyElementObject(&encryptionAlgorithm,
 
1172
            ospvSignatureObject, 
 
1173
            OSPEDRID_SIG_SGNDAT_SGNINF_DIGENCRYPTALG);
 
1174
 
 
1175
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1176
        {
 
1177
            /* Get the signature next */
 
1178
            errorcode = OSPPASN1ObjectCopyElementObject(&encryptedDigest,
 
1179
                ospvSignatureObject, 
 
1180
                OSPEDRID_SIG_SGNDAT_SGNINF_ENCRYPTEDDIGEST);
 
1181
 
 
1182
        }
 
1183
 
 
1184
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1185
        {
 
1186
            /* Get the signer public key from the signers certificate,
 
1187
                Only have ONE certificate in signatures, so it is NOT
 
1188
                necessary to search for certificate, In the future this
 
1189
                might be necessary if certificate chains and/or
 
1190
                multiple signers are allowed.  This is where the code
 
1191
                would be enhanced......BKL */
 
1192
 
 
1193
            errorcode = OSPPASN1ObjectCopyElementObject(&subjPubKeyInfo,
 
1194
                ospvSignatureObject, 
 
1195
                OSPEDRID_SIG_SGNDAT_CERTIFICATE_SUBJPUBKEYINFO);
 
1196
        }
 
1197
 
 
1198
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1199
        {
 
1200
            /* Have the public key data */ 
 
1201
            errorcode = OSPPCryptoDecrypt(&decryptedDigestObject, 
 
1202
                encryptionAlgorithm, encryptedDigest,
 
1203
                subjPubKeyInfo);
 
1204
        }
 
1205
    }
 
1206
 
 
1207
 
 
1208
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1209
    {
 
1210
        /* Now we have a decrypted digest in object form and the 
 
1211
        digest generated from the content - compare them */
 
1212
 
 
1213
        errorcode = OSPPASN1ObjectGetElementInfo(decryptedDigestObject, &eInfo);
 
1214
 
 
1215
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1216
        {
 
1217
            errorcode = OSPPASN1ElementGetContentData(eInfo, 
 
1218
                &decryptedDigest, &decryptedDigestLength);
 
1219
        }
 
1220
 
 
1221
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1222
        {
 
1223
            errorcode = OSPC_ERR_PKCS7_INVALID_SIGNATURE;
 
1224
 
 
1225
            if (decryptedDigestLength == contentDigestLength)
 
1226
            {
 
1227
                if (OSPM_MEMCMP(decryptedDigest, 
 
1228
                    contentDigest, contentDigestLength) == 0)
 
1229
                {
 
1230
                    errorcode = OSPC_ERR_NO_ERROR;
 
1231
                }
 
1232
            }
 
1233
        }
 
1234
    }
 
1235
 
 
1236
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1237
    {
 
1238
        /* Signature is good.  Now test signer certificate to make sure it
 
1239
        is valid and properly signed and authorized */
 
1240
 
 
1241
        /* Get the signer certificate */
 
1242
        errorcode = OSPPASN1ObjectCopyElementObject(&signerCertificate,
 
1243
            ospvSignatureObject, 
 
1244
            OSPEDRID_SIG_SGNDAT_CERTIFICATE);
 
1245
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1246
        {
 
1247
            int ix=0;
 
1248
 
 
1249
            /* Test valid signer certificate against CA certificates */
 
1250
            errorcode = OSPPX509CertValidateCertificate(signerCertificate, 
 
1251
                ospvAuthorityCertificates, 
 
1252
                ospvNumberOfAuthorityCertificates,&ix);
 
1253
        }
 
1254
        if(OSPC_OSNULL!=signerCertificate)  /* !!! PS */
 
1255
        {
 
1256
            OSPPASN1ElementDelete(&(signerCertificate->ParseResults->ElementInfo),0);
 
1257
            OSPPASN1ObjectDelete(&signerCertificate);
 
1258
        }
 
1259
    }
 
1260
    if(OSPC_OSNULL!=subjPubKeyInfo) /* !!! PS */
 
1261
    {
 
1262
        OSPPASN1ElementDelete(&(subjPubKeyInfo->ParseResults->ElementInfo),0);
 
1263
        OSPPASN1ObjectDelete(&subjPubKeyInfo);
 
1264
    }
 
1265
    if(OSPC_OSNULL!=digestAlgorithmId)  /* !!! PS */
 
1266
    {
 
1267
        OSPPASN1ElementDelete(&(digestAlgorithmId->ParseResults->ElementInfo),0);
 
1268
        OSPPASN1ObjectDelete(&digestAlgorithmId);
 
1269
    }
 
1270
    if(OSPC_OSNULL!=encryptionAlgorithm)    /* !!! PS */
 
1271
    {
 
1272
        OSPPASN1ElementDelete(&(encryptionAlgorithm->ParseResults->ElementInfo),0);
 
1273
        OSPPASN1ObjectDelete(&encryptionAlgorithm);
 
1274
    }
 
1275
    if(OSPC_OSNULL!=encryptedDigest)    /* !!! PS */
 
1276
    {
 
1277
        OSPPASN1ElementDelete(&(encryptedDigest->ParseResults->ElementInfo),0);
 
1278
        OSPPASN1ObjectDelete(&encryptedDigest);
 
1279
    }
 
1280
    if(OSPC_OSNULL!=decryptedDigestObject)  /* !!! PS */
 
1281
    {
 
1282
        OSPPASN1ObjectDelete(&decryptedDigestObject);
 
1283
    }
 
1284
    if(OSPC_OSNULL!=digestInfo) /* !!! PS */
 
1285
    {
 
1286
        OSPPASN1ObjectDelete(&digestInfo);
 
1287
    }
 
1288
    return errorcode;
 
1289
} /* OSPPPKCS7SignatureVerify */
 
1290
 
 
1291
 
 
1292
/* EOF */