1
/**************************************************************************
2
*** COPYRIGHT (c) 2002 by TransNexus, Inc. ***
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. ***
13
*** Thank you for using the OSP ToolKit(TM). Please report any bugs, ***
14
*** suggestions or feedback to support@transnexus.com ***
16
**************************************************************************/
25
* osppkcs7.c - PKCS #7 Cryptographic message object processing functions.
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); }
40
#define OSPC_ERR_PKCS7 (25500)
41
#define OSPC_ERR_PKCS7_MALLOC_FAILED (OSPC_ERR_PKCS7 + 1000)
44
/* FUNCTION PROTOTYPES */
46
/* ---------------------------------------------------------*/
47
/* Member functions */
48
/* ---------------------------------------------------------*/
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 */
62
int errorcode = OSPC_ERR_NO_ERROR;
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;
74
/* Generate an ASN1 Encoded PKCS7 Signed Data signature from the
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.
81
/* Encode the content as and OctetString. */
82
errorcode = OSPPASN1OctetStringEncode(&dataContent, ospvContent,
83
ospvContentLength, OSPEDRID_CNTINF_CONTENT);
85
if (errorcode == OSPC_ERR_NO_ERROR)
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. */
91
errorcode = OSPPPKCS7ContentInfoCreate(&contentObject, dataContent,
92
OSPEID_DATA, ospvSignatureOnly);
95
if (errorcode == OSPC_ERR_NO_ERROR)
97
/* Generate the Set of Certificates */
98
errorcode = OSPPPKCS7CertificatesCreate(&certificates,
102
if (errorcode == OSPC_ERR_NO_ERROR)
104
/* Generate the set of DigestAlgorithms */
105
errorcode = OSPPPKCS7DigestAlgorithmsCreate(&digestAlgorithms,
106
ospvDigestAlgorithm);
110
if (errorcode == OSPC_ERR_NO_ERROR)
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,
117
ospvSignerPrivateKey);
120
if (errorcode == OSPC_ERR_NO_ERROR)
122
/* Generate the Set of Signer Info structures. */
123
errorcode = OSPPPKCS7SignerInfosCreate(&signerInfos,
127
if (errorcode == OSPC_ERR_NO_ERROR)
129
/* First, create the signed data object using the function parameters.*/
130
errorcode = OSPPPKCS7SignedDataCreate(&signedData, contentObject,
131
digestAlgorithms, certificates,
135
if (errorcode == OSPC_ERR_NO_ERROR)
137
/* Next, create a ContentInfo with type SignedData. */
138
errorcode = OSPPPKCS7ContentInfoCreate(&contentInfo,signedData,
139
OSPEID_SIGNEDDATA, 0 );
142
if (errorcode == OSPC_ERR_NO_ERROR)
144
errorcode = OSPPASN1ObjectGetElementByDataRef(contentInfo, &eInfo,
145
OSPEDRID_CONTENTINFO);
147
if (errorcode == OSPC_ERR_NO_ERROR)
149
errorcode = OSPPASN1ElementCopyElementData(eInfo,
150
ospvSignature, ospvSignatureLength);
154
OSPPASN1ObjectDelete(&certificates);
155
OSPPASN1ObjectDelete(&digestAlgorithms);
156
OSPPASN1ObjectDelete(&signerInfo);
157
OSPPASN1ObjectDelete(&dataContent);
158
OSPPASN1ObjectDelete(&signerInfos);
159
OSPPASN1ObjectDelete(&signedData);
161
OSPPASN1ObjectDelete(&contentInfo);
162
OSPPASN1ElementDelete(&eInfo, 0);
163
OSPPASN1ObjectDelete(&contentObject);
170
OSPPPKCS7DigestInfoCreate(
171
OSPTASN1OBJECT **ospvDigestInfo,
172
OSPTASN1OBJECT *ospvDigestAlgorithm,
173
unsigned char *ospvContent,
174
unsigned int ospvContentLength)
176
int errorcode = OSPC_ERR_NO_ERROR;
177
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
178
OSPTASN1OBJECT *digestInfo = OSPC_OSNULL;
179
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
184
errorcode = OSPPASN1ObjectNew(&digestInfo, OSPEDRID_DIGESTINFO);
186
for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
190
case 0: /* Add Digest Algorithm */
191
dataRefId = OSPEDRID_DIGINF_DIGESTALGORITHM;
192
errorcode = OSPPASN1ObjectCopy(&newObject,ospvDigestAlgorithm);
193
if(newObject) /* !!! PS */
195
OSPM_FREE(newObject->ElementInfo->Element);
196
OSPM_FREE(newObject->ElementInfo);
200
case 1: /* Add Digest */
201
dataRefId = OSPEDRID_DIGINF_DIGEST;
202
if(newObject) /* !!! PS */
204
OSPM_FREE(newObject->ElementInfo->Element);
205
OSPM_FREE(newObject->ElementInfo);
207
errorcode = OSPPCryptoDigest( &newObject, ospvDigestAlgorithm,
208
ospvContent, ospvContentLength);
213
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
217
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
218
OSPM_DBGERRORLOG(errorcode,
219
"Unknown case encountered encoding PKCS7 DigestInfoCreate");
222
if (errorcode == OSPC_ERR_NO_ERROR)
224
/* Add new object to this object */
225
if (newObject != OSPC_OSNULL)
227
errorcode = OSPPASN1ObjectAddChild( digestInfo, newObject,
229
OSPM_FREE(newObject);
230
newObject = OSPC_OSNULL;
234
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
236
errorcode = OSPC_ERR_NO_ERROR;
239
if (errorcode == OSPC_ERR_NO_ERROR)
241
/* Complete the encoding for this object. Update results, elements,
243
errorcode = OSPPASN1ObjectDeparse(digestInfo, OSPEPTID_DIGESTINFO,
244
OSPEDRID_DIGESTINFO);
247
if (errorcode == OSPC_ERR_NO_ERROR)
249
*ospvDigestInfo = digestInfo;
253
/* Clean up from errors */
254
OSPPASN1ObjectDelete(&digestInfo);
263
OSPPPKCS7SignerInfoCreate(
264
OSPTASN1OBJECT **ospvSignerInfo,
265
OSPTASN1OBJECT *ospvDataContent,
266
OSPTASN1OBJECT *ospvDigestAlgorithm,
267
OSPTASN1OBJECT *ospvSignerCertInfo,
268
OSPTASN1OBJECT *ospvSignerPrivateKey)
270
int errorcode = OSPC_ERR_NO_ERROR;
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;
279
unsigned char *contentData = OSPC_OSNULL;
280
unsigned int contentDataLength = 0;
284
/*The Signature is a ContentInfo structure with a datatype of signedData
287
errorcode = OSPPASN1ObjectNew(&signerInfo, OSPEDRID_SIGNERINFO);
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++)
295
case 0: /* Add VERSION Element */
296
dataRefId = OSPEDRID_SGNINF_VERSION;
297
errorcode = OSPPASN1SmallIntegerEncode(&newObject,
298
OSPC_ASN1_SIGNERINFO_VERSION,
302
case 1: /* Add Issuer */
303
dataRefId = OSPEDRID_SGNINF_ISSUER;
304
errorcode = OSPPASN1ObjectCopyElementObject(
307
OSPEDRID_CERT_ISSUER);
308
if(newObject != OSPC_OSNULL)
310
if(newObject->ElementInfo != OSPC_OSNULL)
312
OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
317
case 2: /* Add SerialNumber */
318
dataRefId = OSPEDRID_SGNINF_SERIALNUMBER;
319
errorcode = OSPPASN1ObjectCopyElementObject(&newObject,
321
OSPEDRID_CERT_SERIALNUMBER);
322
if(newObject != OSPC_OSNULL)
324
if(newObject->ElementInfo != OSPC_OSNULL)
326
OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
331
case 3: /* Add DigestAlgorithm */
332
dataRefId = OSPEDRID_SGNINF_DIGESTALGORITHM;
333
errorcode = OSPPASN1ObjectCopy(&newObject,
334
ospvDigestAlgorithm);
335
if(newObject != OSPC_OSNULL)
337
if(newObject->ElementInfo != OSPC_OSNULL)
339
OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
344
case 4: /* Add AuthenticatedAttributes */
345
dataRefId = OSPEDRID_SGNINF_AUTHATTRIBUTES;
348
case 5: /* Add DigestEncryptionAlgorithm */
349
dataRefId = OSPEDRID_SGNINF_DIGENCRYPTALG;
350
errorcode = OSPPASN1ObjectCopyElementObject(&newObject,
352
OSPEDRID_CERT_PUBLICKEYALG);
353
if(newObject != OSPC_OSNULL)
355
if(newObject->ElementInfo != OSPC_OSNULL)
357
OSPPASN1ElementDelete(&(newObject->ElementInfo) , 0);
362
case 6: /* Add EncryptedDigest */
363
dataRefId = OSPEDRID_SGNINF_ENCRYPTEDDIGEST;
364
errorcode = OSPPASN1ObjectGetElementInfo(ospvDataContent,
368
if (errorcode == OSPC_ERR_NO_ERROR)
370
errorcode = OSPPASN1ElementGetContentData(eInfo,
371
&contentData, &contentDataLength);
375
if (errorcode == OSPC_ERR_NO_ERROR)
377
errorcode = OSPPPKCS7DigestInfoCreate(&digestInfo,
379
contentData, contentDataLength);
382
if (errorcode == OSPC_ERR_NO_ERROR)
384
errorcode = OSPPASN1ObjectCopyElementObject(
385
&digestEncryptionAlgorithm,
387
OSPEDRID_CERT_PUBLICKEYALG);
390
if (errorcode == OSPC_ERR_NO_ERROR)
392
unsigned char *pubkeybuf = OSPC_OSNULL;
393
unsigned int pubkeybuflen = 0;
394
OSPTASN1ELEMENTINFO *tmpSignerSubjPubKeyInfo = OSPC_OSNULL;
396
errorcode = OSPPASN1ObjectGetElementByDataRef(
397
ospvSignerCertInfo, &tmpSignerSubjPubKeyInfo,
398
OSPEDRID_CERT_SUBJPUBKEYINFO);
400
errorcode = OSPPASN1ElementGetElementData(
401
tmpSignerSubjPubKeyInfo, &pubkeybuf, &pubkeybuflen);
403
OSPTNLOGDUMP(pubkeybuf, pubkeybuflen,"signer PUB KEY INFO");
406
if (errorcode == OSPC_ERR_NO_ERROR)
408
errorcode = OSPPCryptoEncrypt(&newObject,
409
digestEncryptionAlgorithm,
411
ospvSignerPrivateKey);
413
if(digestInfo != OSPC_OSNULL)
415
OSPPASN1ObjectDelete(&digestInfo);
418
if(digestEncryptionAlgorithm != OSPC_OSNULL)
420
OSPPASN1ElementDelete(&(digestEncryptionAlgorithm->ParseResults->ElementInfo), 0);
421
OSPPASN1ObjectDelete(&digestEncryptionAlgorithm);
425
case 7: /* Add UnAuthenticatedAttributes */
426
dataRefId = OSPEDRID_SGNINF_UNAUTHATTRIBUTES;
427
newObject = OSPC_OSNULL; /* Add nothing */
431
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
435
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
436
OSPM_DBGERRORLOG(errorcode,
437
"Unknown case encountered encoding PKCS7 SignerInfo");
440
if (errorcode == OSPC_ERR_NO_ERROR)
442
/* Add new object to this object */
443
if (newObject != OSPC_OSNULL)
445
errorcode = OSPPASN1ObjectAddChild(signerInfo, newObject,
447
if(newObject != OSPC_OSNULL)
449
OSPM_FREE(newObject);
454
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
456
errorcode = OSPC_ERR_NO_ERROR;
459
if (errorcode == OSPC_ERR_NO_ERROR)
461
/* Complete the encoding for this object. Update results, elements,
463
errorcode = OSPPASN1ObjectDeparse(signerInfo,
465
OSPEDRID_SIGNERINFO);
469
if (errorcode == OSPC_ERR_NO_ERROR)
471
*ospvSignerInfo = signerInfo;
475
/* Clean up from errors */
476
OSPPASN1ObjectDelete(&signerInfo);
479
if(digestInfo != OSPC_OSNULL)
481
OSPM_FREE(digestInfo);
488
OSPPPKCS7DigestAlgorithmsCreate(
489
OSPTASN1OBJECT **ospvDigestAlgorithms,
490
OSPTASN1OBJECT *ospvDigestAlgorithm)
492
int errorcode=OSPC_ERR_NO_ERROR;
494
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
495
OSPTASN1OBJECT *digestAlgorithms = OSPC_OSNULL;
496
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
500
errorcode = OSPPASN1ObjectNew(&digestAlgorithms,
501
OSPEDRID_SGNDAT_DIGESTALGORITHMS);
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++)
509
case 0: /* Add DigestAlgorithm */
510
dataRefId = OSPEDRID_SGNDAT_DIGESTALGORITHM;
511
errorcode = OSPPASN1ObjectCopy(&newObject, ospvDigestAlgorithm);
512
if(newObject != OSPC_OSNULL)
514
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
519
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
523
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
524
OSPM_DBGERRORLOG(errorcode,
525
"Unknown case encountered encoding PKCS7 DigestAlgorithms");
528
if (errorcode == OSPC_ERR_NO_ERROR)
530
/* Add new object to this object */
531
if (newObject != OSPC_OSNULL)
533
errorcode = OSPPASN1ObjectAddChild(digestAlgorithms, newObject,
535
OSPM_FREE(newObject);
539
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
541
errorcode = OSPC_ERR_NO_ERROR;
544
if (errorcode == OSPC_ERR_NO_ERROR)
546
/* Complete the encoding for this object. Update results, elements,
548
errorcode = OSPPASN1ObjectDeparse(digestAlgorithms,
549
OSPEPTID_DIGESTALGORITHMS,
550
OSPEDRID_SGNDAT_DIGESTALGORITHMS);
553
if (errorcode == OSPC_ERR_NO_ERROR)
555
*ospvDigestAlgorithms = digestAlgorithms;
559
/* Clean up from errors */
560
OSPPASN1ObjectDelete(&digestAlgorithms);
568
OSPPPKCS7CertificatesCreate(
569
OSPTASN1OBJECT **ospvCertificates,
570
OSPTASN1OBJECT *ospvCertificate)
572
int errorcode = OSPC_ERR_NO_ERROR;
574
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
575
OSPTASN1OBJECT *certificates = OSPC_OSNULL;
576
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
580
errorcode = OSPPASN1ObjectNew(&certificates,
581
OSPEDRID_SGNDAT_CERTIFICATES);
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++)
589
case 0: /* Add Certificate */
590
dataRefId = OSPEDRID_SGNDAT_CERTIFICATE;
591
errorcode = OSPPASN1ObjectCopy(&newObject, ospvCertificate);
592
if(newObject->ElementInfo->Element != OSPC_OSNULL)
594
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
599
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
603
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
604
OSPM_DBGERRORLOG(errorcode,
605
"Unknown case encountered encoding PKCS7 Certificates");
608
if (errorcode == OSPC_ERR_NO_ERROR)
610
/* Add new object to this object */
611
if (newObject != OSPC_OSNULL)
613
errorcode = OSPPASN1ObjectAddChild(certificates, newObject,
615
OSPM_FREE(newObject);
619
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
621
errorcode = OSPC_ERR_NO_ERROR;
624
if (errorcode == OSPC_ERR_NO_ERROR)
626
/* Complete the encoding for this object. Update results, elements,
628
errorcode = OSPPASN1ObjectDeparse(certificates,
629
OSPEPTID_CERTIFICATES,
630
OSPEDRID_SGNDAT_CERTIFICATES);
633
if (errorcode == OSPC_ERR_NO_ERROR)
635
*ospvCertificates = certificates;
639
/* Clean up from errors */
640
OSPPASN1ObjectDelete(&certificates);
648
OSPPPKCS7SignerInfosCreate(
649
OSPTASN1OBJECT **ospvSignerInfos,
650
OSPTASN1OBJECT *ospvSignerInfo)
652
int errorcode = OSPC_ERR_NO_ERROR;
654
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
655
OSPTASN1OBJECT *signerInfos = OSPC_OSNULL;
656
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
660
errorcode = OSPPASN1ObjectNew(&signerInfos, OSPEDRID_SGNDAT_SIGNERINFOS);
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++)
668
case 0: /* Add SignerInfo */
669
dataRefId = OSPEDRID_SGNDAT_SIGNERINFO;
670
errorcode = OSPPASN1ObjectCopy(&newObject, ospvSignerInfo);
671
if(newObject->ElementInfo->Element != OSPC_OSNULL)
673
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
678
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
682
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
683
OSPM_DBGERRORLOG(errorcode,
684
"Unknown case encountered encoding PKCS7 SignerInfos");
687
if (errorcode == OSPC_ERR_NO_ERROR)
689
/* Add new object to this object */
690
if (newObject != OSPC_OSNULL)
692
errorcode = OSPPASN1ObjectAddChild(signerInfos, newObject,
694
if(newObject != OSPC_OSNULL)
696
OSPM_FREE(newObject);
701
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
703
errorcode = OSPC_ERR_NO_ERROR;
706
if (errorcode == OSPC_ERR_NO_ERROR)
708
/* Complete the encoding for this object. Update results, elements,
710
errorcode = OSPPASN1ObjectDeparse(signerInfos,
711
OSPEPTID_SIGNERINFOS,
712
OSPEDRID_SGNDAT_SIGNERINFOS);
715
if (errorcode == OSPC_ERR_NO_ERROR)
717
*ospvSignerInfos = signerInfos;
721
/* Clean up from errors */
722
OSPPASN1ObjectDelete(&signerInfos);
730
OSPPPKCS7SignedDataCreate(
731
OSPTASN1OBJECT **ospvSignedData,
732
OSPTASN1OBJECT *ospvContentInfo,
733
OSPTASN1OBJECT *ospvDigestAlgorithms,
734
OSPTASN1OBJECT *ospvSignerCertificates,
735
OSPTASN1OBJECT *ospvSignerInfos)
737
int errorcode = OSPC_ERR_NO_ERROR;
740
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
742
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
743
OSPTASN1OBJECT *signedData = OSPC_OSNULL;
745
errorcode = OSPPASN1ObjectNew(&signedData, OSPEDRID_SIGNEDDATA);
747
for (i = 0 ;errorcode == OSPC_ERR_NO_ERROR ; i++)
752
dataRefId = OSPEDRID_SGNDAT_VERSION;
753
errorcode = OSPPASN1SmallIntegerEncode(&newObject,
754
OSPC_PKCS7_SIGNEDDATA_VERSION,
759
dataRefId = OSPEDRID_SGNDAT_DIGESTALGORITHMS;
760
errorcode = OSPPASN1ObjectCopy(&newObject,
761
ospvDigestAlgorithms);
762
if(newObject != OSPC_OSNULL)
764
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
769
dataRefId = OSPEDRID_SGNDAT_CONTENTINFO;
770
errorcode = OSPPASN1ObjectCopy(&newObject,
772
if(newObject != OSPC_OSNULL)
774
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
779
dataRefId = OSPEDRID_SGNDAT_CERTIFICATES;
780
errorcode = OSPPASN1ObjectCopy(&newObject,
781
ospvSignerCertificates);
782
if(newObject != OSPC_OSNULL)
784
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
789
dataRefId = OSPEDRID_SGNDAT_SIGNERINFOS;
790
errorcode = OSPPASN1ObjectCopy(&newObject,
792
if(newObject != OSPC_OSNULL)
794
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
799
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
803
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
804
OSPM_DBGERRORLOG(errorcode,
805
"Unknown case encountered encoding PKCS7 SignedData");
808
if (errorcode == OSPC_ERR_NO_ERROR)
810
/* Add new object to this object */
811
if (newObject != OSPC_OSNULL)
813
errorcode = OSPPASN1ObjectAddChild(signedData, newObject,
815
OSPM_FREE(newObject);
820
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
822
errorcode = OSPC_ERR_NO_ERROR;
825
if (errorcode == OSPC_ERR_NO_ERROR)
827
errorcode = OSPPASN1ObjectDeparse(signedData,
829
OSPEDRID_SIGNEDDATA);
831
if (errorcode == OSPC_ERR_NO_ERROR)
833
*ospvSignedData = signedData;
838
/* Clean up from errors */
839
OSPPASN1ObjectDelete(&signedData);
842
if(newObject != OSPC_OSNULL)
844
OSPPASN1ObjectDelete(&newObject);
853
OSPPPKCS7ContentInfoCreate(
854
OSPTASN1OBJECT **ospvContentInfo,
855
OSPTASN1OBJECT *ospvContent,
856
OSPEASN1ID ospvContentTypeId,
857
int ospvSignatureOnly)
862
OSPEASN1DATAREFID dataRefId = OSPEDRID_NOTDEFINED;
863
OSPEASN1PARSETABLEID tableId = OSPEPTID_NOTDEFINED;
865
OSPTASN1OBJECT *newObject = OSPC_OSNULL;
866
OSPTASN1OBJECT *contentInfo = OSPC_OSNULL;
868
/*The Signature is a ContentInfo sturcture with a datatype of signedData
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. */
878
/* Signed Data structure will contain element info pointer (null), and
879
a parse results table containing populated data elements with data
882
/* Content type is SignedData. Content may or may not be contained in
883
the signed data structure. */
885
/* Create a content info object for the signature */
886
errorcode = OSPPASN1ObjectNew(&contentInfo, OSPEDRID_CONTENTINFO);
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++)
895
dataRefId = OSPEDRID_CNTINF_CONTENTTYPE;
896
errorcode = OSPPASN1ObjectIdentifierEncode(&newObject,
902
dataRefId = OSPEDRID_CNTINF_CONTENT;
903
if ((ospvSignatureOnly) && (newObject != OSPC_OSNULL))
905
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
909
errorcode = OSPPASN1ObjectCopy(&newObject,ospvContent);
910
if(newObject != OSPC_OSNULL)
912
OSPPASN1ElementDelete(&(newObject->ElementInfo), 0);
918
errorcode = OSPC_ERR_ASN1_PARSE_COMPLETE;
922
errorcode = OSPC_ERR_PKCS7_ENCODING_ERROR;
923
OSPM_DBGERRORLOG(errorcode,
924
"Unknown case encountered encoding PKCS7 ContentInfo.");
927
if (errorcode == OSPC_ERR_NO_ERROR)
929
/* Add new object to this object */
930
if (newObject != OSPC_OSNULL)
932
errorcode = OSPPASN1ObjectAddChild(contentInfo, newObject,
934
OSPM_FREE(newObject);
939
if (errorcode == OSPC_ERR_ASN1_PARSE_COMPLETE)
941
errorcode = OSPC_ERR_NO_ERROR;
944
if (errorcode == OSPC_ERR_NO_ERROR)
946
if (ospvContentTypeId == OSPEID_DATA)
948
tableId = OSPEPTID_CONTENTINFO_DATA;
950
else if (ospvContentTypeId == OSPEID_SIGNEDDATA)
952
tableId = OSPEPTID_CONTENTINFO_SIGNEDDATA;
956
errorcode = OSPC_ERR_ASN1_PARSE_ERROR;
957
OSPM_DBGERRORLOG(errorcode,
958
"Unsupported contentInfo type specified");
961
if (errorcode == OSPC_ERR_NO_ERROR)
963
errorcode = OSPPASN1ObjectDeparse(contentInfo, tableId,
964
OSPEDRID_CONTENTINFO);
968
if (errorcode == OSPC_ERR_NO_ERROR)
970
*ospvContentInfo = contentInfo;
974
OSPPASN1ObjectDelete(&contentInfo);
975
/* Do the cleanup stuff here */
978
if(newObject != OSPC_OSNULL)
980
OSPPASN1ObjectDelete(&newObject);
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.
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.
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.
1003
OSPPPKCS7SignatureParse(
1004
OSPTASN1OBJECT **ospvSignatureObject,
1005
unsigned char *ospvSignature,
1006
unsigned int ospvSignatureLength)
1008
int errorcode = OSPC_ERR_NO_ERROR;
1009
OSPTASN1OBJECT *signatureObject = OSPC_OSNULL;
1010
OSPTASN1ELEMENTINFO *eInfo = OSPC_OSNULL;
1011
OSPTASN1PARSERESULT *parseResults = OSPC_OSNULL;
1013
if ((ospvSignatureObject == OSPC_OSNULL) ||
1014
(ospvSignature == OSPC_OSNULL) ||
1015
(ospvSignatureLength == 0))
1017
errorcode = OSPC_ERR_PKCS7_INVALID_POINTER;
1018
OSPM_DBGERRORLOG(errorcode, "Invalid input or output pointers");
1021
if (errorcode == OSPC_ERR_NO_ERROR)
1023
/* Decode the signature into element and build element list */
1024
errorcode = OSPPASN1ElementDecode(ospvSignature, &eInfo, 0);
1027
if (errorcode == OSPC_ERR_NO_ERROR)
1029
/* Parse the element list to validate structure and get cross
1030
reference list elements */
1031
errorcode = OSPPASN1ElementParse( eInfo,
1032
OSPEPTID_CONTENTINFO_SIGNEDDATA,
1035
OSPC_ASN1_DATAREFID_CONTENTINFO);
1039
if (errorcode == OSPC_ERR_NO_ERROR)
1041
/* Create the signatureObject object that will contain the
1042
decoded/parsed signature */
1043
errorcode = OSPPASN1ObjectCreate(&signatureObject, eInfo, parseResults);
1048
if (errorcode == OSPC_ERR_NO_ERROR)
1050
*ospvSignatureObject = signatureObject;
1059
OSPPPKCS7SignatureGetContent(
1060
OSPTASN1OBJECT *ospvSignatureObject,
1061
unsigned char **ospvContent,
1062
unsigned int *ospvContentLength,
1063
OSPTASN1ELEMENTINFO **el )
1065
int errorcode = OSPC_ERR_NO_ERROR;
1066
OSPTASN1ELEMENTINFO *contentElement = OSPC_OSNULL;
1067
unsigned char *content = OSPC_OSNULL;
1068
unsigned int contentLength = 0;
1070
/* Extract content from signature object */
1071
errorcode = OSPPASN1ObjectGetElementByDataRef(
1072
ospvSignatureObject, &contentElement,
1073
OSPEDRID_SIG_SGNDAT_DATA);
1075
if (errorcode == OSPC_ERR_NO_ERROR)
1077
/* Now we have the data element that should contain the data that
1080
/* Get pointer to data and set length */
1081
errorcode = OSPPASN1ElementGetContentData(contentElement,
1082
&content, &contentLength);
1084
if (errorcode == OSPC_ERR_NO_ERROR)
1086
*ospvContent = content;
1087
*ospvContentLength = contentLength;
1090
if(OSPC_OSNULL!=el) /* !!! PS */
1100
OSPPPKCS7SignatureVerify(
1101
OSPTASN1OBJECT *ospvSignatureObject,
1102
unsigned char *ospvContent,
1103
unsigned int ospvContentLength,
1104
OSPTASN1OBJECT *ospvAuthorityCertificates[],
1105
unsigned int ospvNumberOfAuthorityCertificates)
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;
1121
if ((ospvContent == OSPC_OSNULL) || (ospvContentLength == 0))
1123
errorcode = OSPC_ERR_PKCS7_INVALID_POINTER;
1124
OSPM_DBGERRORLOG(errorcode,
1125
"Content buffer pointer is null, or length is 0");
1129
if (errorcode == OSPC_ERR_NO_ERROR)
1131
/* Now we have the content that was signed and the length.
1132
Need to generate a digest of it for comparison against the
1135
if (errorcode == OSPC_ERR_NO_ERROR)
1138
/* Get the digest algorithm id from the signature object. */
1139
errorcode = OSPPASN1ObjectCopyElementObject( &digestAlgorithmId,
1140
ospvSignatureObject,
1141
OSPEDRID_SIG_SGNDAT_SGNINF_DIGESTALGORITHM);
1144
if (errorcode == OSPC_ERR_NO_ERROR)
1146
/* Create a local Digest Info object to compare to results of
1148
errorcode = OSPPPKCS7DigestInfoCreate(&digestInfo,
1150
ospvContent, ospvContentLength);
1152
if (errorcode == OSPC_ERR_NO_ERROR)
1154
errorcode = OSPPASN1ObjectGetElementInfo(digestInfo, &eInfo);
1155
if (errorcode == OSPC_ERR_NO_ERROR)
1157
errorcode = OSPPASN1ElementGetElementData(eInfo,
1158
&contentDigest, &contentDigestLength);
1165
if (errorcode == OSPC_ERR_NO_ERROR)
1167
/* Ok, now we have a digest of the content, Decrypt the
1168
signature to get the digest that was encrypted and compare the
1171
errorcode = OSPPASN1ObjectCopyElementObject(&encryptionAlgorithm,
1172
ospvSignatureObject,
1173
OSPEDRID_SIG_SGNDAT_SGNINF_DIGENCRYPTALG);
1175
if (errorcode == OSPC_ERR_NO_ERROR)
1177
/* Get the signature next */
1178
errorcode = OSPPASN1ObjectCopyElementObject(&encryptedDigest,
1179
ospvSignatureObject,
1180
OSPEDRID_SIG_SGNDAT_SGNINF_ENCRYPTEDDIGEST);
1184
if (errorcode == OSPC_ERR_NO_ERROR)
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 */
1193
errorcode = OSPPASN1ObjectCopyElementObject(&subjPubKeyInfo,
1194
ospvSignatureObject,
1195
OSPEDRID_SIG_SGNDAT_CERTIFICATE_SUBJPUBKEYINFO);
1198
if (errorcode == OSPC_ERR_NO_ERROR)
1200
/* Have the public key data */
1201
errorcode = OSPPCryptoDecrypt(&decryptedDigestObject,
1202
encryptionAlgorithm, encryptedDigest,
1208
if (errorcode == OSPC_ERR_NO_ERROR)
1210
/* Now we have a decrypted digest in object form and the
1211
digest generated from the content - compare them */
1213
errorcode = OSPPASN1ObjectGetElementInfo(decryptedDigestObject, &eInfo);
1215
if (errorcode == OSPC_ERR_NO_ERROR)
1217
errorcode = OSPPASN1ElementGetContentData(eInfo,
1218
&decryptedDigest, &decryptedDigestLength);
1221
if (errorcode == OSPC_ERR_NO_ERROR)
1223
errorcode = OSPC_ERR_PKCS7_INVALID_SIGNATURE;
1225
if (decryptedDigestLength == contentDigestLength)
1227
if (OSPM_MEMCMP(decryptedDigest,
1228
contentDigest, contentDigestLength) == 0)
1230
errorcode = OSPC_ERR_NO_ERROR;
1236
if (errorcode == OSPC_ERR_NO_ERROR)
1238
/* Signature is good. Now test signer certificate to make sure it
1239
is valid and properly signed and authorized */
1241
/* Get the signer certificate */
1242
errorcode = OSPPASN1ObjectCopyElementObject(&signerCertificate,
1243
ospvSignatureObject,
1244
OSPEDRID_SIG_SGNDAT_CERTIFICATE);
1245
if (errorcode == OSPC_ERR_NO_ERROR)
1249
/* Test valid signer certificate against CA certificates */
1250
errorcode = OSPPX509CertValidateCertificate(signerCertificate,
1251
ospvAuthorityCertificates,
1252
ospvNumberOfAuthorityCertificates,&ix);
1254
if(OSPC_OSNULL!=signerCertificate) /* !!! PS */
1256
OSPPASN1ElementDelete(&(signerCertificate->ParseResults->ElementInfo),0);
1257
OSPPASN1ObjectDelete(&signerCertificate);
1260
if(OSPC_OSNULL!=subjPubKeyInfo) /* !!! PS */
1262
OSPPASN1ElementDelete(&(subjPubKeyInfo->ParseResults->ElementInfo),0);
1263
OSPPASN1ObjectDelete(&subjPubKeyInfo);
1265
if(OSPC_OSNULL!=digestAlgorithmId) /* !!! PS */
1267
OSPPASN1ElementDelete(&(digestAlgorithmId->ParseResults->ElementInfo),0);
1268
OSPPASN1ObjectDelete(&digestAlgorithmId);
1270
if(OSPC_OSNULL!=encryptionAlgorithm) /* !!! PS */
1272
OSPPASN1ElementDelete(&(encryptionAlgorithm->ParseResults->ElementInfo),0);
1273
OSPPASN1ObjectDelete(&encryptionAlgorithm);
1275
if(OSPC_OSNULL!=encryptedDigest) /* !!! PS */
1277
OSPPASN1ElementDelete(&(encryptedDigest->ParseResults->ElementInfo),0);
1278
OSPPASN1ObjectDelete(&encryptedDigest);
1280
if(OSPC_OSNULL!=decryptedDigestObject) /* !!! PS */
1282
OSPPASN1ObjectDelete(&decryptedDigestObject);
1284
if(OSPC_OSNULL!=digestInfo) /* !!! PS */
1286
OSPPASN1ObjectDelete(&digestInfo);
1289
} /* OSPPPKCS7SignatureVerify */