108 lines
3.5 KiB
Diff
108 lines
3.5 KiB
Diff
|
From 6850ae623f9d36b70f1d2919c8390a4b14d393a1 Mon Sep 17 00:00:00 2001
|
||
|
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||
|
Date: Mon, 6 Jul 2020 13:16:01 +0200
|
||
|
Subject: [PATCH 5/5] Fix storing of public token objects in new data format
|
||
|
|
||
|
The tokversion and object length field are supposed to be stored
|
||
|
in big endian (BE) on all platforms. This was not the case for public
|
||
|
token objects.
|
||
|
|
||
|
Fix this by always storing it in BE, and add logic to the read routines
|
||
|
to automatically detect if the fields are in the expected byte order,
|
||
|
or not, and handle them accordingly.
|
||
|
|
||
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||
|
---
|
||
|
usr/lib/common/loadsave.c | 32 +++++++++++++++++++++++++++-----
|
||
|
1 file changed, 27 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
|
||
|
index 068fdf36..b76dea9f 100644
|
||
|
--- a/usr/lib/common/loadsave.c
|
||
|
+++ b/usr/lib/common/loadsave.c
|
||
|
@@ -2557,6 +2557,7 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||
|
CK_ULONG size_64;
|
||
|
CK_RV rc;
|
||
|
uint32_t len;
|
||
|
+ uint32_t ver;
|
||
|
|
||
|
if (tokdata->version < TOK_NEW_DATA_STORE)
|
||
|
return reload_token_object_old(tokdata, obj);
|
||
|
@@ -2580,9 +2581,18 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
+ memcpy(&ver, header, 4);
|
||
|
memcpy(&priv, header + 4, 1);
|
||
|
memcpy(&len, header + 60, 4);
|
||
|
- size = be32toh(len);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * In OCK 3.12 - 3.14 the version and size was not stored in BE. So if
|
||
|
+ * version field is in platform endianness, keep size as is also.
|
||
|
+ */
|
||
|
+ if (ver == TOK_NEW_DATA_STORE)
|
||
|
+ size = len;
|
||
|
+ else
|
||
|
+ size = be32toh(len);
|
||
|
|
||
|
buf = (CK_BYTE *) malloc(size);
|
||
|
if (buf == NULL) {
|
||
|
@@ -2647,8 +2657,9 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||
|
CK_ULONG clear_len;
|
||
|
CK_BBOOL flag = FALSE;
|
||
|
CK_RV rc;
|
||
|
- CK_ULONG_32 len;
|
||
|
+ CK_ULONG_32 len, be_len;
|
||
|
unsigned char reserved[7] = {0};
|
||
|
+ uint32_t tmp;
|
||
|
|
||
|
if (tokdata->version < TOK_NEW_DATA_STORE)
|
||
|
return save_public_token_object_old(tokdata, obj);
|
||
|
@@ -2669,11 +2680,14 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
+ tmp = htobe32(tokdata->version);
|
||
|
+ be_len = htobe32(len);
|
||
|
+
|
||
|
set_perm(fileno(fp));
|
||
|
- if (fwrite(&tokdata->version, 4, 1, fp) != 1
|
||
|
+ if (fwrite(&tmp, 4, 1, fp) != 1
|
||
|
|| fwrite(&flag, 1, 1, fp) != 1
|
||
|
|| fwrite(reserved, 7, 1, fp) != 1
|
||
|
- || fwrite(&len, 4, 1, fp) != 1
|
||
|
+ || fwrite(&be_len, 4, 1, fp) != 1
|
||
|
|| fwrite(clear, len, 1, fp) != 1) {
|
||
|
rc = CKR_FUNCTION_FAILED;
|
||
|
goto done;
|
||
|
@@ -2704,6 +2718,7 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata)
|
||
|
CK_BBOOL priv;
|
||
|
CK_ULONG_32 size;
|
||
|
unsigned char header[PUB_HEADER_LEN];
|
||
|
+ uint32_t ver;
|
||
|
|
||
|
if (tokdata->version < TOK_NEW_DATA_STORE)
|
||
|
return load_public_token_objects_old(tokdata);
|
||
|
@@ -2731,9 +2746,16 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata)
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
+ memcpy(&ver, header, 4);
|
||
|
memcpy(&priv, header + 4, 1);
|
||
|
memcpy(&size, header + 12, 4);
|
||
|
- size = be32toh(size);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * In OCK 3.12 - 3.14 the version and size was not stored in BE. So if
|
||
|
+ * version field is in platform endianness, keep size as is also
|
||
|
+ */
|
||
|
+ if (ver != TOK_NEW_DATA_STORE)
|
||
|
+ size = be32toh(size);
|
||
|
|
||
|
if (priv == TRUE) {
|
||
|
fclose(fp2);
|
||
|
--
|
||
|
2.16.2.windows.1
|
||
|
|