Skip to content

Commit 90590b0

Browse files
David Woodhousedwmw2
authored andcommitted
Serialize to RFC7512-compliant PKCS#11 URIs
Signed-off-by: David Woodhouse <[email protected]>
1 parent 4d5280d commit 90590b0

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
@@ -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+
83172
CK_RV
84173
pkcs11h_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

Comments
 (0)