From 6ba56d23e489a38f42ed7b518bd25ae2192ed651 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 3 Feb 2020 13:50:49 -0500 Subject: [PATCH 84/86] Add some x509 helpers. Signed-off-by: Peter Jones --- src/efisec.h | 2 ++ src/x509.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/x509.h diff --git a/src/efisec.h b/src/efisec.h index 15d0f6d10e2..ef874da0356 100644 --- a/src/efisec.h +++ b/src/efisec.h @@ -8,6 +8,8 @@ #define PRIVATE_EFISEC_H_ #include "efivar.h" +#include "x509.h" + #include #endif /* !PRIVATE_EFISEC_H_ */ diff --git a/src/x509.h b/src/x509.h new file mode 100644 index 00000000000..16aef081bfa --- /dev/null +++ b/src/x509.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * x509.h - X.509/ASN.1 helper functions + * Copyright 2019-2020 Peter M. Jones + */ +#ifndef EFIVAR_X509_H +#define EFIVAR_X509_H + +#define SMALLEST_POSSIBLE_DER_SEQ 3 + +static inline int32_t +__attribute__((unused)) +get_asn1_seq_size(uint8_t *location, uint32_t size) +{ + uint8_t i; + uint8_t octets; + uint32_t der_len = 0; + + if (size < SMALLEST_POSSIBLE_DER_SEQ) + return -1; + + // If it's not a CONSTRUCTED SEQUENCE it's not a certificate + if (location[0] != 0x30) + return -1; + + if (!(location[1] & 0x80)) { + // Short form, which is too small to hold a certificate. + return -1; + } + + // Long form + octets = location[1] & 0x7; + + // There is no chance our data is more than 3GB. + if (octets > 4 || (octets == 4 && (location[2] & 0x8))) + return -1; + + // and if our size won't fit in the data it's wrong as well + if (size - 2 < octets) + return -1; + + for (i = 0; i < octets; i++) { + der_len <<= 8; + der_len |= location[i + 2]; + } + // and if der_len is greater than what's left, it's bad too. + if (size - 2 - octets < der_len) + return -1; + + // or else it's a reasonable certificate from a size point of view. + return der_len + 4; +} + +#undef SMALLEST_POSSIBLE_DER_SEQ + +#endif -- 2.24.1