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