From c0d7ce22131ae2879533ad85d73ee4faa02f2d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Cie=C5=9Blak?= Date: Sat, 28 Sep 2024 00:57:02 +0200 Subject: [PATCH 1/3] serialization: escape all bytes except known characters --- lib/pkcs11h-serialization.c | 8 +++++--- lib/pkcs11h-util.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/pkcs11h-serialization.c b/lib/pkcs11h-serialization.c index 74b4ca71..d5845a27 100644 --- a/lib/pkcs11h-serialization.c +++ b/lib/pkcs11h-serialization.c @@ -56,7 +56,9 @@ #include "_pkcs11h-token.h" #include "_pkcs11h-certificate.h" -#define __PKCS11H_SERIALIZE_INVALID_CHARS "\\/\"'%&#@!?$* <>{}[]()`|:;,.+-" +#define __PKCS11H_SERIALIZE_VALID_CHARS "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "0123456789_-." #if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE) @@ -99,7 +101,7 @@ pkcs11h_token_serializeTokenId ( NULL, sources[e], &t, - __PKCS11H_SERIALIZE_INVALID_CHARS + __PKCS11H_SERIALIZE_VALID_CHARS )) != CKR_OK ) { goto cleanup; @@ -121,7 +123,7 @@ pkcs11h_token_serializeTokenId ( sz+n, sources[e], &t, - __PKCS11H_SERIALIZE_INVALID_CHARS + __PKCS11H_SERIALIZE_VALID_CHARS )) != CKR_OK ) { goto cleanup; diff --git a/lib/pkcs11h-util.c b/lib/pkcs11h-util.c index 7325db44..d70955db 100644 --- a/lib/pkcs11h-util.c +++ b/lib/pkcs11h-util.c @@ -148,7 +148,7 @@ _pkcs11h_util_escapeString ( IN OUT char * const target, IN const char * const source, IN size_t * const max, - IN const char * const invalid_chars + IN const char * const valid_chars ) { static const char *x = "0123456789ABCDEF"; CK_RV rv = CKR_FUNCTION_FAILED; @@ -162,7 +162,7 @@ _pkcs11h_util_escapeString ( while (*s != '\x0') { - if (*s == '\\' || strchr (invalid_chars, (unsigned char)*s) || !isgraph (*s)) { + if (!strchr (valid_chars, (unsigned char)*s)) { if (t != NULL) { if (n+4 > *max) { rv = CKR_ATTRIBUTE_VALUE_INVALID; From 05287282380130c2db6919549770470d88b0b991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Cie=C5=9Blak?= Date: Sat, 28 Sep 2024 01:51:33 +0200 Subject: [PATCH 2/3] serialization: unescape URL encoded values --- lib/pkcs11h-util.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/pkcs11h-util.c b/lib/pkcs11h-util.c index d70955db..7da5d3d8 100644 --- a/lib/pkcs11h-util.c +++ b/lib/pkcs11h-util.c @@ -225,13 +225,22 @@ _pkcs11h_util_unescapeString ( const char *s = source; char *t = target; size_t n = 0; + size_t bytes_per_esc; + int high_nibble_pos; /*_PKCS11H_ASSERT (target!=NULL); Not required*/ _PKCS11H_ASSERT (source!=NULL); _PKCS11H_ASSERT (max!=NULL); while (*s != '\x0') { - if (*s == '\\') { + if (*s == '\\' || *s == '%') { + if (*s == '%') { + bytes_per_esc = 3; + high_nibble_pos = 1; + } else { + bytes_per_esc = 4; + high_nibble_pos = 2; + } if (t != NULL) { if (n+1 > *max) { rv = CKR_ATTRIBUTE_VALUE_INVALID; @@ -240,15 +249,15 @@ _pkcs11h_util_unescapeString ( else { char b[3]; unsigned u; - b[0] = s[2]; - b[1] = s[3]; + b[0] = s[high_nibble_pos]; + b[1] = s[high_nibble_pos+1]; b[2] = '\x0'; sscanf (b, "%08x", &u); *t = (char)(u & 0xff); t++; } } - s+=4; + s+=bytes_per_esc; } else { if (t != NULL) { From 4fe8d589f32997564c9fe87257761ba4fca5453b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Cie=C5=9Blak?= Date: Sat, 28 Sep 2024 13:24:48 +0200 Subject: [PATCH 3/3] serialization: use URL encoding --- lib/_pkcs11h-util.h | 6 ++++-- lib/pkcs11h-serialization.c | 26 ++++++++++++++-------- lib/pkcs11h-util.c | 43 +++++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/lib/_pkcs11h-util.h b/lib/_pkcs11h-util.h index e9237af1..6064765e 100644 --- a/lib/_pkcs11h-util.h +++ b/lib/_pkcs11h-util.h @@ -74,7 +74,8 @@ _pkcs11h_util_binaryToHex ( OUT char * const target, IN const size_t target_size, IN const unsigned char * const source, - IN const size_t source_size + IN const size_t source_size, + IN int url_escape ); CK_RV @@ -82,7 +83,8 @@ _pkcs11h_util_escapeString ( IN OUT char * const target, IN const char * const source, IN size_t * const max, - IN const char * const invalid_chars + IN const char * const invalid_chars, + IN int url_escape ); CK_RV diff --git a/lib/pkcs11h-serialization.c b/lib/pkcs11h-serialization.c index d5845a27..63b07ea5 100644 --- a/lib/pkcs11h-serialization.c +++ b/lib/pkcs11h-serialization.c @@ -56,6 +56,7 @@ #include "_pkcs11h-token.h" #include "_pkcs11h-certificate.h" +#define __PKCS11H_SERIALIZE_AS_PKCS11_URI 1 #define __PKCS11H_SERIALIZE_VALID_CHARS "abcdefghijklmnopqrstuvwxyz" \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "0123456789_-." @@ -101,7 +102,8 @@ pkcs11h_token_serializeTokenId ( NULL, sources[e], &t, - __PKCS11H_SERIALIZE_VALID_CHARS + __PKCS11H_SERIALIZE_VALID_CHARS, + __PKCS11H_SERIALIZE_AS_PKCS11_URI )) != CKR_OK ) { goto cleanup; @@ -123,7 +125,8 @@ pkcs11h_token_serializeTokenId ( sz+n, sources[e], &t, - __PKCS11H_SERIALIZE_VALID_CHARS + __PKCS11H_SERIALIZE_VALID_CHARS, + __PKCS11H_SERIALIZE_AS_PKCS11_URI )) != CKR_OK ) { goto cleanup; @@ -327,7 +330,7 @@ pkcs11h_certificate_serializeCertificateId ( goto cleanup; } - _max = n + certificate_id->attrCKA_ID_size*2 + 1; + _max = n + certificate_id->attrCKA_ID_size*3 + 1; if (sz != NULL) { if (saved_max < _max) { @@ -336,12 +339,17 @@ pkcs11h_certificate_serializeCertificateId ( } sz[n-1] = '/'; - rv = _pkcs11h_util_binaryToHex ( - sz+n, - saved_max-n, - certificate_id->attrCKA_ID, - certificate_id->attrCKA_ID_size - ); + if ( + (rv = _pkcs11h_util_binaryToHex ( + sz+n, + saved_max-n, + certificate_id->attrCKA_ID, + certificate_id->attrCKA_ID_size, + __PKCS11H_SERIALIZE_AS_PKCS11_URI + )) != CKR_OK + ) { + goto cleanup; + } } *max = _max; diff --git a/lib/pkcs11h-util.c b/lib/pkcs11h-util.c index 7da5d3d8..2772e854 100644 --- a/lib/pkcs11h-util.c +++ b/lib/pkcs11h-util.c @@ -122,23 +122,29 @@ _pkcs11h_util_binaryToHex ( OUT char * const target, IN const size_t target_size, IN const unsigned char * const source, - IN const size_t source_size + IN const size_t source_size, + IN int url_escape ) { static const char *x = "0123456789ABCDEF"; - size_t i; + size_t i, t; + size_t bytes_per_esc = url_escape ? 3 : 2; _PKCS11H_ASSERT (target!=NULL); _PKCS11H_ASSERT (source!=NULL); - if (target_size < source_size * 2 + 1) { + if (target_size < source_size * bytes_per_esc + 1) { return CKR_ATTRIBUTE_VALUE_INVALID; } for (i=0;i>4]; - target[i*2+1] = x[(source[i]&0x0f)>>0]; + t = i*bytes_per_esc; + if (url_escape) { + target[t++] = '%'; + } + target[t++] = x[(source[i]&0xf0)>>4]; + target[t++] = x[(source[i]&0x0f)>>0]; } - target[source_size*2] = '\x0'; + target[source_size*bytes_per_esc] = '\x0'; return CKR_OK; } @@ -148,13 +154,15 @@ _pkcs11h_util_escapeString ( IN OUT char * const target, IN const char * const source, IN size_t * const max, - IN const char * const valid_chars + IN const char * const valid_chars, + IN const int url_escape ) { static const char *x = "0123456789ABCDEF"; CK_RV rv = CKR_FUNCTION_FAILED; const char *s = source; char *t = target; size_t n = 0; + size_t bytes_per_esc = url_escape ? 3 : 4; /*_PKCS11H_ASSERT (target!=NULL); Not required*/ _PKCS11H_ASSERT (source!=NULL); @@ -164,19 +172,26 @@ _pkcs11h_util_escapeString ( if (!strchr (valid_chars, (unsigned char)*s)) { if (t != NULL) { - if (n+4 > *max) { + if (n+bytes_per_esc > *max) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } else { - t[0] = '\\'; - t[1] = 'x'; - t[2] = x[(*s&0xf0)>>4]; - t[3] = x[(*s&0x0f)>>0]; - t+=4; + if (url_escape) { + t[0] = '%'; + t[1] = x[(*s&0xf0)>>4]; + t[2] = x[(*s&0x0f)>>0]; + t+=3; + } else { + t[0] = '\\'; + t[1] = 'x'; + t[2] = x[(*s&0xf0)>>4]; + t[3] = x[(*s&0x0f)>>0]; + t+=4; + } } } - n+=4; + n+=bytes_per_esc; } else { if (t != NULL) {