diff --git a/src/openvpn/base64.h b/src/openvpn/base64.h index f49860fc65a..7b4224a51b4 100644 --- a/src/openvpn/base64.h +++ b/src/openvpn/base64.h @@ -38,6 +38,10 @@ #define OPENVPN_BASE64_LENGTH(binary_length) \ ((((8 * binary_length) / 6) + 3) & ~3) +/** Compute the maximal number of bytes encoded in a base64 string. */ +#define OPENVPN_BASE64_DECODED_LENGTH(base64_length) \ + ((base64_length / 4) * 3) + int openvpn_base64_encode(const void *data, int size, char **str); int openvpn_base64_decode(const char *str, void *data, int size); diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c index 2fc79111936..1e461fcf6b5 100644 --- a/src/openvpn/tls_crypt.c +++ b/src/openvpn/tls_crypt.c @@ -627,15 +627,11 @@ tls_crypt_v2_write_client_key_file(const char *filename, } ASSERT(buf_write(&dst, client_key.keys, sizeof(client_key.keys))); - struct buffer metadata = alloc_buf_gc(TLS_CRYPT_V2_MAX_METADATA_LEN, &gc); + struct buffer metadata; if (b64_metadata) { - if (TLS_CRYPT_V2_MAX_B64_METADATA_LEN < strlen(b64_metadata)) - { - msg(M_FATAL, - "ERROR: metadata too long (%d bytes, max %u bytes)", - (int)strlen(b64_metadata), TLS_CRYPT_V2_MAX_B64_METADATA_LEN); - } + size_t b64_length = strlen(b64_metadata); + metadata = alloc_buf_gc(OPENVPN_BASE64_DECODED_LENGTH(b64_length) + 1, &gc); ASSERT(buf_write(&metadata, &TLS_CRYPT_METADATA_TYPE_USER, 1)); int decoded_len = openvpn_base64_decode(b64_metadata, BEND(&metadata), BCAP(&metadata)); @@ -644,10 +640,18 @@ tls_crypt_v2_write_client_key_file(const char *filename, msg(M_FATAL, "ERROR: failed to base64 decode provided metadata"); goto cleanup; } + if (decoded_len > TLS_CRYPT_V2_MAX_METADATA_LEN - 1) + { + msg(M_FATAL, + "ERROR: metadata too long (%d bytes, max %u bytes)", + decoded_len, TLS_CRYPT_V2_MAX_METADATA_LEN - 1); + goto cleanup; + } ASSERT(buf_inc_len(&metadata, decoded_len)); } else { + metadata = alloc_buf_gc(1 + sizeof(int64_t), &gc); int64_t timestamp = htonll((uint64_t)now); ASSERT(buf_write(&metadata, &TLS_CRYPT_METADATA_TYPE_TIMESTAMP, 1)); ASSERT(buf_write(&metadata, ×tamp, sizeof(timestamp))); diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h index 928ff547583..d5c73752370 100644 --- a/src/openvpn/tls_crypt.h +++ b/src/openvpn/tls_crypt.h @@ -101,8 +101,6 @@ #define TLS_CRYPT_V2_MAX_METADATA_LEN (unsigned)(TLS_CRYPT_V2_MAX_WKC_LEN \ - (TLS_CRYPT_V2_CLIENT_KEY_LEN + TLS_CRYPT_V2_TAG_SIZE \ + sizeof(uint16_t))) -#define TLS_CRYPT_V2_MAX_B64_METADATA_LEN \ - OPENVPN_BASE64_LENGTH(TLS_CRYPT_V2_MAX_METADATA_LEN - 1) /** * Initialize a key_ctx_bi structure for use with --tls-crypt.