2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is the Netscape security libraries.
14
* The Initial Developer of the Original Code is Netscape
15
* Communications Corporation. Portions created by Netscape are
16
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
21
* Alternatively, the contents of this file may be used under the
22
* terms of the GNU General Public License Version 2 or later (the
23
* "GPL"), in which case the provisions of the GPL are applicable
24
* instead of those above. If you wish to allow use of your
25
* version of this file only under the terms of the GPL and not to
26
* allow others to use your version of this file under the MPL,
27
* indicate your decision by deleting the provisions above and
28
* replace them with the notice and other provisions required by
29
* the GPL. If you do not delete the provisions above, a recipient
30
* may use your version of this file under either the MPL or the
35
static const char CVS_ID[] = "@(#) $RCSfile: asn1.c,v $ $Revision: 1.2 $ $Date: 2001/11/08 00:14:34 $ $Name: FIREFOX_1_0_RELEASE $";
41
* At this point in time, this file contains the NSS wrappers for
42
* the old "SEC" ASN.1 encoder/decoder stuff.
53
* The pointer-tracking stuff
57
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
59
static nssPointerTracker decoder_pointer_tracker;
64
const nssASN1Decoder *decoder
69
rv = nssPointerTracker_initialize(&decoder_pointer_tracker);
70
if( PR_SUCCESS != rv ) {
74
rv = nssPointerTracker_add(&decoder_pointer_tracker, decoder);
75
if( PR_SUCCESS != rv ) {
76
NSSError e = NSS_GetError();
77
if( NSS_ERROR_NO_MEMORY != e ) {
78
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
88
decoder_remove_pointer
90
const nssASN1Decoder *decoder
95
rv = nssPointerTracker_remove(&decoder_pointer_tracker, decoder);
96
if( PR_SUCCESS != rv ) {
97
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
104
* nssASN1Decoder_verify
106
* This routine is only available in debug builds.
108
* If the specified pointer is a valid pointer to an nssASN1Decoder
109
* object, this routine will return PR_SUCCESS. Otherwise, it will
110
* put an error on the error stack and return PR_FAILURE.
112
* The error may be one of the following values:
113
* NSS_ERROR_INVALID_ASN1DECODER
116
* PR_FAILURE upon error
117
* PR_SUCCESS upon success
120
NSS_IMPLEMENT PRStatus
121
nssASN1Decoder_verify
123
nssASN1Decoder *decoder
128
rv = nssPointerTracker_initialize(&decoder_pointer_tracker);
129
if( PR_SUCCESS != rv ) {
133
rv = nssPointerTracker_verify(&decoder_pointer_tracker, decoder);
134
if( PR_SUCCESS != rv ) {
135
nss_SetError(NSS_ERROR_INVALID_ASN1DECODER);
142
static nssPointerTracker encoder_pointer_tracker;
147
const nssASN1Encoder *encoder
152
rv = nssPointerTracker_initialize(&encoder_pointer_tracker);
153
if( PR_SUCCESS != rv ) {
157
rv = nssPointerTracker_add(&encoder_pointer_tracker, encoder);
158
if( PR_SUCCESS != rv ) {
159
NSSError e = NSS_GetError();
160
if( NSS_ERROR_NO_MEMORY != e ) {
161
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
171
encoder_remove_pointer
173
const nssASN1Encoder *encoder
178
rv = nssPointerTracker_remove(&encoder_pointer_tracker, encoder);
179
if( PR_SUCCESS != rv ) {
180
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
187
* nssASN1Encoder_verify
189
* This routine is only available in debug builds.
191
* If the specified pointer is a valid pointer to an nssASN1Encoder
192
* object, this routine will return PR_SUCCESS. Otherwise, it will
193
* put an error on the error stack and return PR_FAILURE.
195
* The error may be one of the following values:
196
* NSS_ERROR_INVALID_ASN1ENCODER
199
* PR_FAILURE upon error
200
* PR_SUCCESS upon success
203
NSS_IMPLEMENT PRStatus
204
nssASN1Encoder_verify
206
nssASN1Encoder *encoder
211
rv = nssPointerTracker_initialize(&encoder_pointer_tracker);
212
if( PR_SUCCESS != rv ) {
216
rv = nssPointerTracker_verify(&encoder_pointer_tracker, encoder);
217
if( PR_SUCCESS != rv ) {
218
nss_SetError(NSS_ERROR_INVALID_ASN1ENCODER);
227
* nssASN1Decoder_Create
229
* This routine creates an ASN.1 Decoder, which will use the specified
230
* template to decode a datastream into the specified destination
231
* structure. If the optional arena argument is non-NULL, blah blah
232
* blah. XXX fgmr Should we include an nssASN1EncodingType argument,
233
* as a hint? Or is each encoding distinctive? This routine may
234
* return NULL upon error, in which case an error will have been
235
* placed upon the error stack.
237
* The error may be one of the following values:
238
* NSS_ERROR_NO_MEMORY
239
* NSS_ERROR_INVALID_ARENA
240
* NSS_ERROR_INVALID_POINTER
245
* A pointer to an ASN.1 Decoder upon success.
248
NSS_IMPLEMENT nssASN1Decoder *
249
nssASN1Decoder_Create
253
const nssASN1Template template[]
256
SEC_ASN1DecoderContext *rv;
257
PLArenaPool *hack = (PLArenaPool *)arenaOpt;
260
if( (NSSArena *)NULL != arenaOpt ) {
261
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
262
return (nssASN1Decoder *)NULL;
267
* May destination be NULL? I'd think so, since one might
268
* have only a filter proc. But if not, check the pointer here.
271
if( (nssASN1Template *)NULL == template ) {
272
nss_SetError(NSS_ERROR_INVALID_POINTER);
273
return (nssASN1Decoder *)NULL;
277
rv = SEC_ASN1DecoderStart(hack, destination, template);
278
if( (SEC_ASN1DecoderContext *)NULL == rv ) {
279
nss_SetError(PORT_GetError()); /* also evil */
280
return (nssASN1Decoder *)NULL;
284
if( PR_SUCCESS != decoder_add_pointer(rv) ) {
285
(void)SEC_ASN1DecoderFinish(rv);
286
return (nssASN1Decoder *)NULL;
290
return (nssASN1Decoder *)rv;
294
* nssASN1Decoder_Update
296
* This routine feeds data to the decoder. In the event of an error,
297
* it will place an error on the error stack and return PR_FAILURE.
299
* The error may be one of the following values:
300
* NSS_ERROR_NO_MEMORY
301
* NSS_ERROR_INVALID_POINTER
302
* NSS_ERROR_INVALID_ASN1DECODER
303
* NSS_ERROR_INVALID_BER
307
* PR_FAILURE upon error
308
* PR_SUCCESS upon success.
311
NSS_IMPLEMENT PRStatus
312
nssASN1Decoder_Update
314
nssASN1Decoder *decoder,
322
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
326
if( (void *)NULL == data ) {
327
nss_SetError(NSS_ERROR_INVALID_POINTER);
332
rv = SEC_ASN1DecoderUpdate((SEC_ASN1DecoderContext *)decoder,
334
(unsigned long)amount);
335
if( SECSuccess != rv ) {
336
nss_SetError(PORT_GetError()); /* ugly */
344
* nssASN1Decoder_Finish
346
* This routine finishes the decoding and destroys the decoder.
347
* In the event of an error, it will place an error on the error
348
* stack and return PR_FAILURE.
350
* The error may be one of the following values:
351
* NSS_ERROR_INVALID_ASN1DECODER
354
* PR_FAILURE upon error
355
* PR_SUCCESS upon success
358
NSS_IMPLEMENT PRStatus
359
nssASN1Decoder_Finish
361
nssASN1Decoder *decoder
364
PRStatus rv = PR_SUCCESS;
368
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
373
srv = SEC_ASN1DecoderFinish((SEC_ASN1DecoderContext *)decoder);
375
if( SECSuccess != srv ) {
376
nss_SetError(PORT_GetError()); /* ugly */
382
PRStatus rv2 = decoder_remove_pointer(decoder);
383
if( PR_SUCCESS == rv ) {
393
* nssASN1Decoder_SetFilter
395
* This routine registers a callback filter routine with the decoder,
396
* which will be called blah blah blah. The specified argument will
397
* be passed as-is to the filter routine. The routine pointer may
398
* be NULL, in which case no filter callback will be called. If the
399
* noStore boolean is PR_TRUE, then decoded fields will not be stored
400
* in the destination structure specified when the decoder was
401
* created. This routine returns a PRStatus value; in the event of
402
* an error, it will place an error on the error stack and return
405
* The error may be one of the following values:
406
* NSS_ERROR_INVALID_ASN1DECODER
409
* PR_FAILURE upon error
410
* PR_SUCCESS upon success
413
NSS_IMPLEMENT PRStatus
414
nssASN1Decoder_SetFilter
416
nssASN1Decoder *decoder,
417
nssASN1DecoderFilterFunction *callback,
423
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
428
if( (nssASN1DecoderFilterFunction *)NULL == callback ) {
429
SEC_ASN1DecoderClearFilterProc((SEC_ASN1DecoderContext *)decoder);
431
SEC_ASN1DecoderSetFilterProc((SEC_ASN1DecoderContext *)decoder,
432
(SEC_ASN1WriteProc)callback,
436
/* No error returns defined for those routines */
442
* nssASN1Decoder_GetFilter
444
* If the optional pCallbackOpt argument to this routine is non-null,
445
* then the pointer to any callback function established for this
446
* decoder with nssASN1Decoder_SetFilter will be stored at the
447
* location indicated by it. If the optional pArgumentOpt
448
* pointer is non-null, the filter's closure argument will be stored
449
* there. If the optional pNoStoreOpt pointer is non-null, the
450
* noStore value specified when setting the filter will be stored
451
* there. This routine returns a PRStatus value; in the event of
452
* an error it will place an error on the error stack and return
455
* The error may be one of the following values:
456
* NSS_ERROR_INVALID_ASN1DECODER
459
* PR_FAILURE upon error
460
* PR_SUCCESS upon success
463
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
465
NSS_IMPLEMENT PRStatus
466
nssASN1Decoder_GetFilter
468
nssASN1Decoder *decoder,
469
nssASN1DecoderFilterFunction **pCallbackOpt,
475
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
480
if( (nssASN1DecoderFilterFunction **)NULL != pCallbackOpt ) {
481
*pCallbackOpt = (nssASN1DecoderFilterFunction *)NULL;
484
if( (void **)NULL != pArgumentOpt ) {
485
*pArgumentOpt = (void *)NULL;
488
if( (PRBool *)NULL != pNoStoreOpt ) {
489
*pNoStoreOpt = PR_FALSE;
492
/* Error because it's unimplemented */
493
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
498
* nssASN1Decoder_SetNotify
500
* This routine registers a callback notify routine with the decoder,
501
* which will be called whenever.. The specified argument will be
502
* passed as-is to the notify routine. The routine pointer may be
503
* NULL, in which case no notify routine will be called. This routine
504
* returns a PRStatus value; in the event of an error it will place
505
* an error on the error stack and return PR_FAILURE.
507
* The error may be one of the following values:
508
* NSS_ERROR_INVALID_ASN1DECODER
511
* PR_FAILURE upon error
512
* PR_SUCCESS upon success
515
NSS_IMPLEMENT PRStatus
516
nssASN1Decoder_SetNotify
518
nssASN1Decoder *decoder,
519
nssASN1NotifyFunction *callback,
524
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
529
if( (nssASN1NotifyFunction *)NULL == callback ) {
530
SEC_ASN1DecoderClearNotifyProc((SEC_ASN1DecoderContext *)decoder);
532
SEC_ASN1DecoderSetNotifyProc((SEC_ASN1DecoderContext *)decoder,
533
(SEC_ASN1NotifyProc)callback,
537
/* No error returns defined for those routines */
543
* nssASN1Decoder_GetNotify
545
* If the optional pCallbackOpt argument to this routine is non-null,
546
* then the pointer to any callback function established for this
547
* decoder with nssASN1Decoder_SetNotify will be stored at the
548
* location indicated by it. If the optional pArgumentOpt pointer is
549
* non-null, the filter's closure argument will be stored there.
550
* This routine returns a PRStatus value; in the event of an error it
551
* will place an error on the error stack and return PR_FAILURE.
553
* The error may be one of the following values:
554
* NSS_ERROR_INVALID_ASN1DECODER
557
* PR_FAILURE upon error
558
* PR_SUCCESS upon success
561
NSS_IMPLEMENT PRStatus
562
nssASN1Decoder_GetNotify
564
nssASN1Decoder *decoder,
565
nssASN1NotifyFunction **pCallbackOpt,
570
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
575
if( (nssASN1NotifyFunction **)NULL != pCallbackOpt ) {
576
*pCallbackOpt = (nssASN1NotifyFunction *)NULL;
579
if( (void **)NULL != pArgumentOpt ) {
580
*pArgumentOpt = (void *)NULL;
583
/* Error because it's unimplemented */
584
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
591
* This routine will decode the specified data into the specified
592
* destination structure, as specified by the specified template.
593
* This routine returns a PRStatus value; in the event of an error
594
* it will place an error on the error stack and return PR_FAILURE.
596
* The error may be one of the following values:
597
* NSS_ERROR_NO_MEMORY
598
* NSS_ERROR_INVALID_ARENA
599
* NSS_ERROR_INVALID_POINTER
600
* NSS_ERROR_INVALID_BER
603
* PR_FAILURE upon error
604
* PR_SUCCESS upon success
607
NSS_IMPLEMENT PRStatus
612
const nssASN1Template template[],
618
nssASN1Decoder *decoder;
620
/* This call will do our pointer-checking for us! */
621
decoder = nssASN1Decoder_Create(arenaOpt, destination, template);
622
if( (nssASN1Decoder *)NULL == decoder ) {
626
rv = nssASN1Decoder_Update(decoder, berData, amount);
627
if( PR_SUCCESS != nssASN1Decoder_Finish(decoder) ) {
637
* This routine will decode the data in the specified NSSBER
638
* into the destination structure, as specified by the template.
639
* This routine returns a PRStatus value; in the event of an error
640
* it will place an error on the error stack and return PR_FAILURE.
642
* The error may be one of the following values:
643
* NSS_ERROR_NO_MEMORY
644
* NSS_ERROR_INVALID_ARENA
645
* NSS_ERROR_INVALID_POINTER
646
* NSS_ERROR_INVALID_NSSBER
647
* NSS_ERROR_INVALID_BER
650
* PR_FAILURE upon error
651
* PR_SUCCESS upon success
654
NSS_IMPLEMENT PRStatus
659
const nssASN1Template template[],
663
return nssASN1_Decode(arenaOpt, destination, template,
664
data->data, data->size);
668
* nssASN1Encoder_Create
670
* This routine creates an ASN.1 Encoder, blah blah blah. This
671
* may return NULL upon error, in which case an error will have been
672
* placed on the error stack.
674
* The error may be one of the following values:
675
* NSS_ERROR_NO_MEMORY
676
* NSS_ERROR_INVALID_ARENA
677
* NSS_ERROR_INVALID_POINTER
682
* A pointer to an ASN.1 Encoder upon success
685
NSS_IMPLEMENT nssASN1Encoder *
686
nssASN1Encoder_Create
689
const nssASN1Template template[],
690
NSSASN1EncodingType encoding,
691
nssASN1EncoderWriteFunction *sink,
695
SEC_ASN1EncoderContext *rv;
698
if( (void *)NULL == source ) {
699
nss_SetError(NSS_ERROR_INVALID_POINTER);
700
return (nssASN1Encoder *)NULL;
703
if( (nssASN1Template *)NULL == template ) {
704
nss_SetError(NSS_ERROR_INVALID_POINTER);
705
return (nssASN1Encoder *)NULL;
708
if( (nssASN1EncoderWriteFunction *)NULL == sink ) {
709
nss_SetError(NSS_ERROR_INVALID_POINTER);
710
return (nssASN1Encoder *)NULL;
721
case NSSASN1UnknownEncoding:
723
nss_SetError(NSS_ERROR_ENCODING_NOT_SUPPORTED);
724
return (nssASN1Encoder *)NULL;
727
rv = SEC_ASN1EncoderStart((void *)source, template,
728
(SEC_ASN1WriteProc)sink, argument);
729
if( (SEC_ASN1EncoderContext *)NULL == rv ) {
730
nss_SetError(PORT_GetError()); /* ugly */
731
return (nssASN1Encoder *)NULL;
734
if( NSSASN1DER == encoding ) {
735
sec_ASN1EncoderSetDER(rv);
739
if( PR_SUCCESS != encoder_add_pointer(rv) ) {
740
(void)SEC_ASN1EncoderFinish(rv);
741
return (nssASN1Encoder *)NULL;
745
return (nssASN1Encoder *)rv;
749
* nssASN1Encoder_Update
751
* The error may be one of the following values:
752
* NSS_ERROR_INVALID_ASN1ENCODER
753
* NSS_ERROR_INVALID_POINTER
756
* PR_FAILURE upon error
757
* PR_SUCCESS upon success
760
NSS_IMPLEMENT PRStatus
761
nssASN1Encoder_Update
763
nssASN1Encoder *encoder,
771
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
776
* Can data legitimately be NULL? If not, verify..
780
rv = SEC_ASN1EncoderUpdate((SEC_ASN1EncoderContext *)encoder,
782
(unsigned long)length);
783
if( SECSuccess != rv ) {
784
nss_SetError(PORT_GetError()); /* ugly */
792
* nssASN1Encoder_Finish
796
* The error may be one of the following values:
797
* NSS_ERROR_INVALID_ASN1ENCODER
800
* PR_FAILURE upon error
801
* PR_SUCCESS upon success
804
NSS_IMPLEMENT PRStatus
805
nssASN1Encoder_Finish
807
nssASN1Encoder *encoder
813
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
818
SEC_ASN1EncoderFinish((SEC_ASN1EncoderContext *)encoder);
819
rv = PR_SUCCESS; /* no error return defined for that call */
823
PRStatus rv2 = encoder_remove_pointer(encoder);
824
if( PR_SUCCESS == rv ) {
834
* nssASN1Encoder_SetNotify
836
* This routine registers a callback notify routine with the encoder,
837
* which will be called whenever.. The specified argument will be
838
* passed as-is to the notify routine. The routine pointer may be
839
* NULL, in which case no notify routine will be called. This routine
840
* returns a PRStatus value; in the event of an error it will place
841
* an error on the error stack and return PR_FAILURE.
843
* The error may be one of the following values:
844
* NSS_ERROR_INVALID_ASN1DECODER
847
* PR_FAILURE upon error
848
* PR_SUCCESS upon success
851
NSS_IMPLEMENT PRStatus
852
nssASN1Encoder_SetNotify
854
nssASN1Encoder *encoder,
855
nssASN1NotifyFunction *callback,
860
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
865
if( (nssASN1NotifyFunction *)NULL == callback ) {
866
SEC_ASN1EncoderClearNotifyProc((SEC_ASN1EncoderContext *)encoder);
868
SEC_ASN1EncoderSetNotifyProc((SEC_ASN1EncoderContext *)encoder,
869
(SEC_ASN1NotifyProc)callback,
873
/* no error return defined for those routines */
879
* nssASN1Encoder_GetNotify
881
* If the optional pCallbackOpt argument to this routine is non-null,
882
* then the pointer to any callback function established for this
883
* decoder with nssASN1Encoder_SetNotify will be stored at the
884
* location indicated by it. If the optional pArgumentOpt pointer is
885
* non-null, the filter's closure argument will be stored there.
886
* This routine returns a PRStatus value; in the event of an error it
887
* will place an error on the error stack and return PR_FAILURE.
889
* The error may be one of the following values:
890
* NSS_ERROR_INVALID_ASN1ENCODER
893
* PR_FAILURE upon error
894
* PR_SUCCESS upon success
897
NSS_IMPLEMENT PRStatus
898
nssASN1Encoder_GetNotify
900
nssASN1Encoder *encoder,
901
nssASN1NotifyFunction **pCallbackOpt,
906
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
911
if( (nssASN1NotifyFunction **)NULL != pCallbackOpt ) {
912
*pCallbackOpt = (nssASN1NotifyFunction *)NULL;
915
if( (void **)NULL != pArgumentOpt ) {
916
*pArgumentOpt = (void *)NULL;
919
/* Error because it's unimplemented */
920
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
925
* nssASN1Encoder_SetStreaming
928
* The error may be one of the following values:
929
* NSS_ERROR_INVALID_ASN1ENCODER
932
* PR_FAILURE upon error
933
* PR_SUCCESS upon success
936
NSS_IMPLEMENT PRStatus
937
nssASN1Encoder_SetStreaming
939
nssASN1Encoder *encoder,
943
SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext *)encoder;
946
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
952
SEC_ASN1EncoderSetStreaming(cx);
954
SEC_ASN1EncoderClearStreaming(cx);
957
/* no error return defined for those routines */
963
* nssASN1Encoder_GetStreaming
966
* The error may be one of the following values:
967
* NSS_ERROR_INVALID_ASN1ENCODER
968
* NSS_ERROR_INVALID_POINTER
971
* PR_FAILURE upon error
972
* PR_SUCCESS upon success
976
nssASN1Encoder_GetStreaming
978
nssASN1Encoder *encoder,
983
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
988
if( (PRBool *)NULL != pStreaming ) {
989
*pStreaming = PR_FALSE;
992
/* Error because it's unimplemented */
993
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
998
* nssASN1Encoder_SetTakeFromBuffer
1001
* The error may be one of the following values:
1002
* NSS_ERROR_INVALID_ASN1ENCODER
1005
* PR_FAILURE upon error
1006
* PR_SUCCESS upon success
1009
NSS_IMPLEMENT PRStatus
1010
nssASN1Encoder_SetTakeFromBuffer
1012
nssASN1Encoder *encoder,
1013
PRBool takeFromBuffer
1016
SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext *)encoder;
1019
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
1024
if( takeFromBuffer ) {
1025
SEC_ASN1EncoderSetTakeFromBuf(cx);
1027
SEC_ASN1EncoderClearTakeFromBuf(cx);
1030
/* no error return defined for those routines */
1036
* nssASN1Encoder_GetTakeFromBuffer
1039
* The error may be one of the following values:
1040
* NSS_ERROR_INVALID_ASN1ENCODER
1041
* NSS_ERROR_INVALID_POINTER
1044
* PR_FAILURE upon error
1045
* PR_SUCCESS upon success
1048
NSS_IMPLEMENT PRStatus
1049
nssASN1Encoder_GetTakeFromBuffer
1051
nssASN1Encoder *encoder,
1052
PRBool *pTakeFromBuffer
1056
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
1061
if( (PRBool *)NULL != pTakeFromBuffer ) {
1062
*pTakeFromBuffer = PR_FALSE;
1065
/* Error because it's unimplemented */
1066
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
1074
* The error may be one of the following values:
1075
* NSS_ERROR_NO_MEMORY
1076
* NSS_ERROR_INVALID_ARENA
1077
* NSS_ERROR_INVALID_POINTER
1078
* NSS_ERROR_ENCODING_NOT_SUPPORTED
1082
* PR_FAILURE upon error
1083
* PR_SUCCESS upon success
1086
NSS_IMPLEMENT PRStatus
1090
const nssASN1Template template[],
1091
NSSASN1EncodingType encoding,
1092
nssASN1EncoderWriteFunction *sink,
1097
nssASN1Encoder *encoder;
1099
encoder = nssASN1Encoder_Create(source, template, encoding, sink, argument);
1100
if( (nssASN1Encoder *)NULL == encoder ) {
1104
rv = nssASN1Encoder_Update(encoder, (const void *)NULL, 0);
1105
if( PR_SUCCESS != nssASN1Encoder_Finish(encoder) ) {
1113
* nssasn1_encode_item_count
1115
* This is a helper function for nssASN1_EncodeItem. It just counts
1116
* up the space required for an encoding.
1120
nssasn1_encode_item_count
1126
nssASN1EncodingPart data_kind
1129
unsigned long *count;
1131
count = (unsigned long*)arg;
1132
PR_ASSERT (count != NULL);
1138
* nssasn1_encode_item_store
1140
* This is a helper function for nssASN1_EncodeItem. It appends the
1141
* new data onto the destination item.
1145
nssasn1_encode_item_store
1151
nssASN1EncodingPart data_kind
1156
dest = (NSSItem*)arg;
1157
PR_ASSERT (dest != NULL);
1159
memcpy((unsigned char *)dest->data + dest->size, buf, len);
1164
* nssASN1_EncodeItem
1166
* There must be a better name. If the optional arena argument is
1167
* non-null, it'll be used for the space. If the optional rvOpt is
1168
* non-null, it'll be the return value-- if it is null, a new one
1169
* will be allocated.
1171
* The error may be one of the following values:
1172
* NSS_ERROR_NO_MEMORY
1173
* NSS_ERROR_INVALID_ARENA
1174
* NSS_ERROR_INVALID_POINTER
1175
* NSS_ERROR_ENCODING_NOT_SUPPORTED
1179
* A valid pointer to an NSSDER upon success
1182
NSS_IMPLEMENT NSSDER *
1188
const nssASN1Template template[],
1189
NSSASN1EncodingType encoding
1197
if( (NSSArena *)NULL != arenaOpt ) {
1198
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
1199
return (NSSDER *)NULL;
1203
if( (void *)NULL == source ) {
1204
nss_SetError(NSS_ERROR_INVALID_POINTER);
1205
return (NSSDER *)NULL;
1208
if( (nssASN1Template *)NULL == template ) {
1209
nss_SetError(NSS_ERROR_INVALID_POINTER);
1210
return (NSSDER *)NULL;
1214
status = nssASN1_Encode(source, template, encoding,
1215
(nssASN1EncoderWriteFunction *)nssasn1_encode_item_count,
1217
if( PR_SUCCESS != status ) {
1218
return (NSSDER *)NULL;
1221
if( (NSSDER *)NULL == rvOpt ) {
1222
rv = nss_ZNEW(arenaOpt, NSSDER);
1223
if( (NSSDER *)NULL == rv ) {
1224
return (NSSDER *)NULL;
1231
rv->data = nss_ZAlloc(arenaOpt, len);
1232
if( (void *)NULL == rv->data ) {
1233
if( (NSSDER *)NULL == rvOpt ) {
1236
return (NSSDER *)NULL;
1239
rv->size = 0; /* for nssasn1_encode_item_store */
1241
status = nssASN1_Encode(source, template, encoding,
1242
(nssASN1EncoderWriteFunction *)nssasn1_encode_item_store,
1244
if( PR_SUCCESS != status ) {
1245
nss_ZFreeIf(rv->data);
1246
if( (NSSDER *)NULL == rvOpt ) {
1249
return (NSSDER *)NULL;
1252
PR_ASSERT(rv->size == len);
1258
* nssASN1_CreatePRUint32FromBER
1262
NSS_IMPLEMENT PRStatus
1263
nssASN1_CreatePRUint32FromBER
1269
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
1274
* nssASN1_GetDERFromPRUint32
1279
nssASN1_GetDERFromPRUint32
1287
PLArenaPool *hack = (PLArenaPool *)arenaOpt;
1291
if( (NSSArena *)NULL != arenaOpt ) {
1292
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
1293
return (NSSDER *)NULL;
1298
if( (NSSDER *)NULL == rvOpt ) {
1299
rv = nss_ZNEW(arenaOpt, NSSDER);
1300
if( (NSSDER *)NULL == rv ) {
1301
return (NSSDER *)NULL;
1307
item = SEC_ASN1EncodeUnsignedInteger(hack, (SECItem *)rv, value);
1308
if( (SECItem *)NULL == item ) {
1309
if( (NSSDER *)NULL == rvOpt ) {
1310
(void)nss_ZFreeIf(rv);
1313
nss_SetError(PORT_GetError()); /* ugly */
1314
return (NSSDER *)NULL;
1318
* I happen to know that these things look alike.. but I'm only
1319
* doing it for these "temporary" wrappers. This is an evil thing.
1321
return (NSSDER *)item;
1325
NSS_IMPLEMENT PRStatus
1326
nssASN1_CreatePRInt32FromBER
1332
nss_SetError(NSS_ERROR_INTERNAL_ERROR);
1337
* nssASN1_GetDERFromPRInt32
1341
NSS_IMPLEMENT NSSDER *
1342
nssASN1_GetDERFromPRInt32
1350
PLArenaPool *hack = (PLArenaPool *)arenaOpt;
1354
if( (NSSArena *)NULL != arenaOpt ) {
1355
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
1356
return (NSSDER *)NULL;
1361
if( (NSSDER *)NULL == rvOpt ) {
1362
rv = nss_ZNEW(arenaOpt, NSSDER);
1363
if( (NSSDER *)NULL == rv ) {
1364
return (NSSDER *)NULL;
1370
item = SEC_ASN1EncodeInteger(hack, (SECItem *)rv, value);
1371
if( (SECItem *)NULL == item ) {
1372
if( (NSSDER *)NULL == rvOpt ) {
1373
(void)nss_ZFreeIf(rv);
1376
nss_SetError(PORT_GetError()); /* ugly */
1377
return (NSSDER *)NULL;
1381
* I happen to know that these things look alike.. but I'm only
1382
* doing it for these "temporary" wrappers. This is an evil thing.
1384
return (NSSDER *)item;
1389
* One for each of the simple types, plus a special one for ANY, plus:
1390
* - a pointer to each one of those
1391
* - a set of each one of those
1393
* Note that these are alphabetical (case insensitive); please add new
1394
* ones in the appropriate place.
1397
const nssASN1Template *nssASN1Template_Any = (nssASN1Template *)SEC_AnyTemplate;
1398
const nssASN1Template *nssASN1Template_BitString = (nssASN1Template *)SEC_BitStringTemplate;
1399
const nssASN1Template *nssASN1Template_BMPString = (nssASN1Template *)SEC_BMPStringTemplate;
1400
const nssASN1Template *nssASN1Template_Boolean = (nssASN1Template *)SEC_BooleanTemplate;
1401
const nssASN1Template *nssASN1Template_Enumerated = (nssASN1Template *)SEC_EnumeratedTemplate;
1402
const nssASN1Template *nssASN1Template_GeneralizedTime = (nssASN1Template *)SEC_GeneralizedTimeTemplate;
1403
const nssASN1Template *nssASN1Template_IA5String = (nssASN1Template *)SEC_IA5StringTemplate;
1404
const nssASN1Template *nssASN1Template_Integer = (nssASN1Template *)SEC_IntegerTemplate;
1405
const nssASN1Template *nssASN1Template_Null = (nssASN1Template *)SEC_NullTemplate;
1406
const nssASN1Template *nssASN1Template_ObjectID = (nssASN1Template *)SEC_ObjectIDTemplate;
1407
const nssASN1Template *nssASN1Template_OctetString = (nssASN1Template *)SEC_OctetStringTemplate;
1408
const nssASN1Template *nssASN1Template_PrintableString = (nssASN1Template *)SEC_PrintableStringTemplate;
1409
const nssASN1Template *nssASN1Template_T61String = (nssASN1Template *)SEC_T61StringTemplate;
1410
const nssASN1Template *nssASN1Template_UniversalString = (nssASN1Template *)SEC_UniversalStringTemplate;
1411
const nssASN1Template *nssASN1Template_UTCTime = (nssASN1Template *)SEC_UTCTimeTemplate;
1412
const nssASN1Template *nssASN1Template_UTF8String = (nssASN1Template *)SEC_UTF8StringTemplate;
1413
const nssASN1Template *nssASN1Template_VisibleString = (nssASN1Template *)SEC_VisibleStringTemplate;
1415
const nssASN1Template *nssASN1Template_PointerToAny = (nssASN1Template *)SEC_PointerToAnyTemplate;
1416
const nssASN1Template *nssASN1Template_PointerToBitString = (nssASN1Template *)SEC_PointerToBitStringTemplate;
1417
const nssASN1Template *nssASN1Template_PointerToBMPString = (nssASN1Template *)SEC_PointerToBMPStringTemplate;
1418
const nssASN1Template *nssASN1Template_PointerToBoolean = (nssASN1Template *)SEC_PointerToBooleanTemplate;
1419
const nssASN1Template *nssASN1Template_PointerToEnumerated = (nssASN1Template *)SEC_PointerToEnumeratedTemplate;
1420
const nssASN1Template *nssASN1Template_PointerToGeneralizedTime = (nssASN1Template *)SEC_PointerToGeneralizedTimeTemplate;
1421
const nssASN1Template *nssASN1Template_PointerToIA5String = (nssASN1Template *)SEC_PointerToIA5StringTemplate;
1422
const nssASN1Template *nssASN1Template_PointerToInteger = (nssASN1Template *)SEC_PointerToIntegerTemplate;
1423
const nssASN1Template *nssASN1Template_PointerToNull = (nssASN1Template *)SEC_PointerToNullTemplate;
1424
const nssASN1Template *nssASN1Template_PointerToObjectID = (nssASN1Template *)SEC_PointerToObjectIDTemplate;
1425
const nssASN1Template *nssASN1Template_PointerToOctetString = (nssASN1Template *)SEC_PointerToOctetStringTemplate;
1426
const nssASN1Template *nssASN1Template_PointerToPrintableString = (nssASN1Template *)SEC_PointerToPrintableStringTemplate;
1427
const nssASN1Template *nssASN1Template_PointerToT61String = (nssASN1Template *)SEC_PointerToT61StringTemplate;
1428
const nssASN1Template *nssASN1Template_PointerToUniversalString = (nssASN1Template *)SEC_PointerToUniversalStringTemplate;
1429
const nssASN1Template *nssASN1Template_PointerToUTCTime = (nssASN1Template *)SEC_PointerToUTCTimeTemplate;
1430
const nssASN1Template *nssASN1Template_PointerToUTF8String = (nssASN1Template *)SEC_PointerToUTF8StringTemplate;
1431
const nssASN1Template *nssASN1Template_PointerToVisibleString = (nssASN1Template *)SEC_PointerToVisibleStringTemplate;
1433
const nssASN1Template *nssASN1Template_SetOfAny = (nssASN1Template *)SEC_SetOfAnyTemplate;
1434
const nssASN1Template *nssASN1Template_SetOfBitString = (nssASN1Template *)SEC_SetOfBitStringTemplate;
1435
const nssASN1Template *nssASN1Template_SetOfBMPString = (nssASN1Template *)SEC_SetOfBMPStringTemplate;
1436
const nssASN1Template *nssASN1Template_SetOfBoolean = (nssASN1Template *)SEC_SetOfBooleanTemplate;
1437
const nssASN1Template *nssASN1Template_SetOfEnumerated = (nssASN1Template *)SEC_SetOfEnumeratedTemplate;
1438
const nssASN1Template *nssASN1Template_SetOfGeneralizedTime = (nssASN1Template *)SEC_SetOfGeneralizedTimeTemplate;
1439
const nssASN1Template *nssASN1Template_SetOfIA5String = (nssASN1Template *)SEC_SetOfIA5StringTemplate;
1440
const nssASN1Template *nssASN1Template_SetOfInteger = (nssASN1Template *)SEC_SetOfIntegerTemplate;
1441
const nssASN1Template *nssASN1Template_SetOfNull = (nssASN1Template *)SEC_SetOfNullTemplate;
1442
const nssASN1Template *nssASN1Template_SetOfObjectID = (nssASN1Template *)SEC_SetOfObjectIDTemplate;
1443
const nssASN1Template *nssASN1Template_SetOfOctetString = (nssASN1Template *)SEC_SetOfOctetStringTemplate;
1444
const nssASN1Template *nssASN1Template_SetOfPrintableString = (nssASN1Template *)SEC_SetOfPrintableStringTemplate;
1445
const nssASN1Template *nssASN1Template_SetOfT61String = (nssASN1Template *)SEC_SetOfT61StringTemplate;
1446
const nssASN1Template *nssASN1Template_SetOfUniversalString = (nssASN1Template *)SEC_SetOfUniversalStringTemplate;
1447
const nssASN1Template *nssASN1Template_SetOfUTCTime = (nssASN1Template *)SEC_SetOfUTCTimeTemplate;
1448
const nssASN1Template *nssASN1Template_SetOfUTF8String = (nssASN1Template *)SEC_SetOfUTF8StringTemplate;
1449
const nssASN1Template *nssASN1Template_SetOfVisibleString = (nssASN1Template *)SEC_SetOfVisibleStringTemplate;
1455
NSS_IMPLEMENT NSSUTF8 *
1456
nssUTF8_CreateFromBER
1469
const nssASN1Template *templ;
1472
if( (NSSArena *)NULL != arenaOpt ) {
1473
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
1474
return (NSSUTF8 *)NULL;
1478
if( (NSSBER *)NULL == berData ) {
1479
nss_SetError(NSS_ERROR_INVALID_POINTER);
1480
return (NSSUTF8 *)NULL;
1483
if( (void *)NULL == berData->data ) {
1484
nss_SetError(NSS_ERROR_INVALID_POINTER);
1485
return (NSSUTF8 *)NULL;
1487
#endif /* NSSDEBUG */
1489
a = NSSArena_Create();
1490
if( (NSSArena *)NULL == a ) {
1491
return (NSSUTF8 *)NULL;
1497
* By the way, at first I succumbed to the temptation to make
1498
* this an incestuous nested switch statement. Count yourself
1499
* lucky I cleaned it up.
1503
case nssStringType_DirectoryString:
1505
* draft-ietf-pkix-ipki-part1-11 says in part:
1507
* DirectoryString { INTEGER:maxSize } ::= CHOICE {
1508
* teletexString TeletexString (SIZE (1..maxSize)),
1509
* printableString PrintableString (SIZE (1..maxSize)),
1510
* universalString UniversalString (SIZE (1..maxSize)),
1511
* bmpString BMPString (SIZE(1..maxSize)),
1512
* utf8String UTF8String (SIZE(1..maxSize))
1516
* TeletexString UNIVERSAL 20
1517
* PrintableString UNIVERSAL 19
1518
* UniversalString UNIVERSAL 28
1519
* BMPString UNIVERSAL 30
1520
* UTF8String UNIVERSAL 12
1522
* "UNIVERSAL" tags have bits 8 and 7 zero, bit 6 is zero for
1523
* primitive encodings, and if the tag value is less than 30,
1524
* the tag value is directly encoded in bits 5 through 1.
1526
in.data = (void *)&(((PRUint8 *)berData->data)[1]);
1527
in.size = berData->size-1;
1529
tag = *(PRUint8 *)berData->data;
1530
switch( tag & nssASN1_TAGNUM_MASK ) {
1533
* XXX fgmr-- we have to accept Latin-1 for Teletex; (see
1534
* below) but is T61 a suitable value for "Latin-1"?
1536
templ = nssASN1Template_T61String;
1537
type = nssStringType_TeletexString;
1540
templ = nssASN1Template_PrintableString;
1541
type = nssStringType_PrintableString;
1544
templ = nssASN1Template_UniversalString;
1545
type = nssStringType_UniversalString;
1548
templ = nssASN1Template_BMPString;
1549
type = nssStringType_BMPString;
1552
templ = nssASN1Template_UTF8String;
1553
type = nssStringType_UTF8String;
1556
nss_SetError(NSS_ERROR_INVALID_POINTER); /* "pointer"? */
1557
(void)NSSArena_Destroy(a);
1558
return (NSSUTF8 *)NULL;
1563
case nssStringType_TeletexString:
1565
* XXX fgmr-- we have to accept Latin-1 for Teletex; (see
1566
* below) but is T61 a suitable value for "Latin-1"?
1568
templ = nssASN1Template_T61String;
1571
case nssStringType_PrintableString:
1572
templ = nssASN1Template_PrintableString;
1575
case nssStringType_UniversalString:
1576
templ = nssASN1Template_UniversalString;
1579
case nssStringType_BMPString:
1580
templ = nssASN1Template_BMPString;
1583
case nssStringType_UTF8String:
1584
templ = nssASN1Template_UTF8String;
1587
case nssStringType_PHGString:
1588
templ = nssASN1Template_IA5String;
1592
nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
1593
(void)NSSArena_Destroy(a);
1594
return (NSSUTF8 *)NULL;
1597
st = nssASN1_DecodeBER(a, &out, templ, &in);
1599
if( PR_SUCCESS == st ) {
1600
rv = nssUTF8_Create(arenaOpt, type, out.data, out.size);
1602
(void)NSSArena_Destroy(a);
1608
nssUTF8_GetDEREncoding
1612
const NSSUTF8 *string
1615
NSSDER *rv = (NSSDER *)NULL;
1618
const nssASN1Template *templ;
1622
if( (NSSArena *)NULL != arenaOpt ) {
1623
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
1624
return (NSSDER *)NULL;
1628
if( (const NSSUTF8 *)NULL == string ) {
1629
nss_SetError(NSS_ERROR_INVALID_POINTER);
1630
return (NSSDER *)NULL;
1632
#endif /* NSSDEBUG */
1634
str.data = (void *)string;
1635
str.size = nssUTF8_Size(string, (PRStatus *)NULL);
1636
if( 0 == str.size ) {
1637
return (NSSDER *)NULL;
1640
a = NSSArena_Create();
1641
if( (NSSArena *)NULL == a ) {
1642
return (NSSDER *)NULL;
1646
case nssStringType_DirectoryString:
1651
utf = nssASN1_EncodeItem(a, (NSSDER *)NULL, &str,
1652
nssASN1Template_UTF8String,
1654
if( (NSSDER *)NULL == utf ) {
1655
(void)NSSArena_Destroy(a);
1656
return (NSSDER *)NULL;
1659
rv = nss_ZNEW(arenaOpt, NSSDER);
1660
if( (NSSDER *)NULL == rv ) {
1661
(void)NSSArena_Destroy(a);
1662
return (NSSDER *)NULL;
1665
rv->size = utf->size + 1;
1666
rv->data = nss_ZAlloc(arenaOpt, rv->size);
1667
if( (void *)NULL == rv->data ) {
1668
(void)nss_ZFreeIf(rv);
1669
(void)NSSArena_Destroy(a);
1670
return (NSSDER *)NULL;
1673
c = (PRUint8 *)rv->data;
1674
(void)nsslibc_memcpy(&c[1], utf->data, utf->size);
1675
*c = 12; /* UNIVERSAL primitive encoding tag for UTF8String */
1677
(void)NSSArena_Destroy(a);
1680
case nssStringType_TeletexString:
1682
* XXX fgmr-- we have to accept Latin-1 for Teletex; (see
1683
* below) but is T61 a suitable value for "Latin-1"?
1685
templ = nssASN1Template_T61String;
1687
case nssStringType_PrintableString:
1688
templ = nssASN1Template_PrintableString;
1691
case nssStringType_UniversalString:
1692
templ = nssASN1Template_UniversalString;
1695
case nssStringType_BMPString:
1696
templ = nssASN1Template_BMPString;
1699
case nssStringType_UTF8String:
1700
templ = nssASN1Template_UTF8String;
1703
case nssStringType_PHGString:
1704
templ = nssASN1Template_IA5String;
1708
nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
1709
(void)NSSArena_Destroy(a);
1710
return (NSSDER *)NULL;
1713
der = nssUTF8_GetDEREncoding(a, type, string);
1714
if( (NSSItem *)NULL == der ) {
1715
(void)NSSArena_Destroy(a);
1716
return (NSSDER *)NULL;
1719
rv = nssASN1_EncodeItem(arenaOpt, (NSSDER *)NULL, der, templ, NSSASN1DER);
1720
if( (NSSDER *)NULL == rv ) {
1721
(void)NSSArena_Destroy(a);
1722
return (NSSDER *)NULL;
1725
(void)NSSArena_Destroy(a);