Skip to content

Commit 9c7387d

Browse files
David WoodhouseDavid Woodhouse
David Woodhouse
authored and
David Woodhouse
committed
Serialize to RFC7512-compliant PKCS#11 URIs
Signed-off-by: David Woodhouse <[email protected]>
1 parent bf894f3 commit 9c7387d

File tree

1 file changed

+91
-95
lines changed

1 file changed

+91
-95
lines changed

lib/pkcs11h-serialization.c

Lines changed: 91 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
84173
CK_RV
85174
pkcs11h_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

Comments
 (0)