Our hand-rolled BER parser was reading ASN.1 sequence length without
checking if there's a sequence tag (0x10) before it.
--- /dev/null
+#ifndef TINC_GCRYPT_ASN1_H
+#define TINC_GCRYPT_ASN1_H
+
+// https://luca.ntop.org/Teaching/Appunti/asn1.html
+typedef enum {
+ TAG_INTEGER = 2,
+ TAG_SEQUENCE = 16,
+} asn1_tag_t;
+
+#endif // TINC_GCRYPT_ASN1_H
#include "rsa.h"
#include "../logger.h"
#include "../rsa.h"
#include "rsa.h"
#include "../logger.h"
#include "../rsa.h"
-
-static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) {
+static bool ber_skip_sequence(unsigned char **p, size_t *buflen) {
int tag = ber_read_id(p, buflen);
int tag = ber_read_id(p, buflen);
- size_t len = ber_read_len(p, buflen);
-
- if(tag == 0x10) {
- if(result) {
- *result = len;
- }
- return true;
- } else {
- return false;
- }
+ return tag == TAG_SEQUENCE &&
+ ber_read_len(p, buflen) > 0;
}
static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) {
}
static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) {
rsa_t *rsa = xzalloc(sizeof(rsa_t));
rsa_t *rsa = xzalloc(sizeof(rsa_t));
- if(!ber_read_sequence(&derp, &derlen, NULL)
+ if(!ber_skip_sequence(&derp, &derlen)
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|| derlen) {
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|| derlen) {
rsa_t *rsa = xzalloc(sizeof(rsa_t));
rsa_t *rsa = xzalloc(sizeof(rsa_t));
- if(!ber_read_sequence(&derp, &derlen, NULL)
+ if(!ber_skip_sequence(&derp, &derlen)
|| !ber_read_mpi(&derp, &derlen, NULL)
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|| !ber_read_mpi(&derp, &derlen, NULL)
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
#include <gcrypt.h>
#include <assert.h>
#include <gcrypt.h>
#include <assert.h>
#include "rsa.h"
#include "pem.h"
#include "../rsagen.h"
#include "../xalloc.h"
#include "../utils.h"
#include "rsa.h"
#include "pem.h"
#include "../rsagen.h"
#include "../xalloc.h"
#include "../utils.h"
-// ASN.1 tags.
-typedef enum {
- TAG_INTEGER = 2,
- TAG_SEQUENCE = 16,
-} asn1_tag_t;
-
static size_t der_tag_len(size_t n) {
if(n < 128) {
return 2;
static size_t der_tag_len(size_t n) {
if(n < 128) {
return 2;