@@ -80,29 +80,107 @@ static struct {
8080 { NULL },
8181};
8282
83+ #define P11_URL_VERBATIM "abcdefghijklmnopqrstuvwxyz" \
84+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
85+ "0123456789_-."
86+
87+ static
88+ int
89+ __token_attr_escape (char * uri , char * attr , size_t attrlen )
90+ {
91+ int len = 0 , i ;
92+
93+ for (i = 0 ; i < attrlen ; i ++ ) {
94+ if ((attr [i ] != '\x0' ) && strchr (P11_URL_VERBATIM , attr [i ])) {
95+ if (uri ) {
96+ * (uri ++ ) = attr [i ];
97+ }
98+ len ++ ;
99+ } else {
100+ if (uri ) {
101+ sprintf (uri , "%%%02x" , (unsigned char )attr [i ]);
102+ uri += 3 ;
103+ }
104+ len += 3 ;
105+ }
106+ }
107+ return len ;
108+ }
109+
110+ static
111+ CK_RV
112+ __generate_pkcs11_uri (
113+ OUT char * const sz ,
114+ IN OUT size_t * max ,
115+ IN const pkcs11h_certificate_id_t certificate_id ,
116+ IN const pkcs11h_token_id_t token_id
117+ ) {
118+ size_t _max ;
119+ char * p = sz ;
120+ int i ;
121+
122+ _PKCS11H_ASSERT (max != NULL );
123+ _PKCS11H_ASSERT (token_id != NULL );
124+
125+ _max = strlen (URI_SCHEME );
126+ for (i = 0 ; __token_fields [i ].name ; i ++ ) {
127+ char * field = ((char * )token_id ) + __token_fields [i ].field_ofs ;
128+
129+ _max += __token_fields [i ].namelen ;
130+ _max += __token_attr_escape (NULL , field , strlen (field ));
131+ _max ++ ; /* For a semicolon or trailing NUL */
132+ }
133+ if (certificate_id ) {
134+ _max += strlen (";id=" );
135+ _max += __token_attr_escape (NULL ,
136+ (char * )certificate_id -> attrCKA_ID ,
137+ certificate_id -> attrCKA_ID_size );
138+ }
139+
140+ if (!sz ) {
141+ * max = _max ;
142+ return CKR_OK ;
143+ }
144+
145+ if (sz && * max < _max )
146+ return CKR_ATTRIBUTE_VALUE_INVALID ;
147+
148+ p += sprintf (p , URI_SCHEME );
149+ for (i = 0 ; __token_fields [i ].name ; i ++ ) {
150+ char * field = ((char * )token_id ) + __token_fields [i ].field_ofs ;
151+
152+ p += sprintf (p , "%s" , __token_fields [i ].name );
153+ p += __token_attr_escape (p , field , strlen (field ));
154+ * (p ++ ) = ';' ;
155+ }
156+ if (certificate_id ) {
157+ p += sprintf (p , "id=" );
158+ p += __token_attr_escape (p ,
159+ (char * )certificate_id -> attrCKA_ID ,
160+ certificate_id -> attrCKA_ID_size );
161+ } else {
162+ /* Remove the unneeded trailing semicolon */
163+ p -- ;
164+ }
165+ * (p ++ ) = 0 ;
166+
167+ * max = _max ;
168+
169+ return CKR_OK ;
170+ }
171+
83172CK_RV
84173pkcs11h_token_serializeTokenId (
85174 OUT char * const sz ,
86175 IN OUT size_t * max ,
87176 IN const pkcs11h_token_id_t token_id
88177) {
89- const char * sources [5 ];
90178 CK_RV rv = CKR_FUNCTION_FAILED ;
91- size_t n ;
92- int e ;
93179
94180 /*_PKCS11H_ASSERT (sz!=NULL); Not required*/
95181 _PKCS11H_ASSERT (max != NULL );
96182 _PKCS11H_ASSERT (token_id != NULL );
97183
98- { /* Must be after assert */
99- sources [0 ] = token_id -> manufacturerID ;
100- sources [1 ] = token_id -> model ;
101- sources [2 ] = token_id -> serialNumber ;
102- sources [3 ] = token_id -> label ;
103- sources [4 ] = NULL ;
104- }
105-
106184 _PKCS11H_DEBUG (
107185 PKCS11H_LOG_DEBUG2 ,
108186 "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max=" P_Z ", token_id=%p" ,
@@ -111,51 +189,7 @@ pkcs11h_token_serializeTokenId (
111189 (void * )token_id
112190 );
113191
114- n = 0 ;
115- for (e = 0 ;sources [e ] != NULL ;e ++ ) {
116- size_t t ;
117- if (
118- (rv = _pkcs11h_util_escapeString (
119- NULL ,
120- sources [e ],
121- & t ,
122- __PKCS11H_SERIALIZE_INVALID_CHARS
123- )) != CKR_OK
124- ) {
125- goto cleanup ;
126- }
127- n += t ;
128- }
129-
130- if (sz != NULL ) {
131- if (* max < n ) {
132- rv = CKR_ATTRIBUTE_VALUE_INVALID ;
133- goto cleanup ;
134- }
135-
136- n = 0 ;
137- for (e = 0 ;sources [e ] != NULL ;e ++ ) {
138- size_t t = * max - n ;
139- if (
140- (rv = _pkcs11h_util_escapeString (
141- sz + n ,
142- sources [e ],
143- & t ,
144- __PKCS11H_SERIALIZE_INVALID_CHARS
145- )) != CKR_OK
146- ) {
147- goto cleanup ;
148- }
149- n += t ;
150- sz [n - 1 ] = '/' ;
151- }
152- sz [n - 1 ] = '\x0' ;
153- }
154-
155- * max = n ;
156- rv = CKR_OK ;
157-
158- cleanup :
192+ rv = __generate_pkcs11_uri (sz , max , NULL , token_id );
159193
160194 _PKCS11H_DEBUG (
161195 PKCS11H_LOG_DEBUG2 ,
@@ -474,9 +508,6 @@ pkcs11h_certificate_serializeCertificateId (
474508 IN const pkcs11h_certificate_id_t certificate_id
475509) {
476510 CK_RV rv = CKR_FUNCTION_FAILED ;
477- size_t saved_max = 0 ;
478- size_t n = 0 ;
479- size_t _max = 0 ;
480511
481512 /*_PKCS11H_ASSERT (sz!=NULL); Not required */
482513 _PKCS11H_ASSERT (max != NULL );
@@ -490,42 +521,7 @@ pkcs11h_certificate_serializeCertificateId (
490521 (void * )certificate_id
491522 );
492523
493- if (sz != NULL ) {
494- saved_max = n = * max ;
495- }
496- * max = 0 ;
497-
498- if (
499- (rv = pkcs11h_token_serializeTokenId (
500- sz ,
501- & n ,
502- certificate_id -> token_id
503- )) != CKR_OK
504- ) {
505- goto cleanup ;
506- }
507-
508- _max = n + certificate_id -> attrCKA_ID_size * 2 + 1 ;
509-
510- if (sz != NULL ) {
511- if (saved_max < _max ) {
512- rv = CKR_ATTRIBUTE_VALUE_INVALID ;
513- goto cleanup ;
514- }
515-
516- sz [n - 1 ] = '/' ;
517- rv = _pkcs11h_util_binaryToHex (
518- sz + n ,
519- saved_max - n ,
520- certificate_id -> attrCKA_ID ,
521- certificate_id -> attrCKA_ID_size
522- );
523- }
524-
525- * max = _max ;
526- rv = CKR_OK ;
527-
528- cleanup :
524+ rv = __generate_pkcs11_uri (sz , max , certificate_id , certificate_id -> token_id );
529525
530526 _PKCS11H_DEBUG (
531527 PKCS11H_LOG_DEBUG2 ,
0 commit comments