Skip to content

Instantly share code, notes, and snippets.

@earlephilhower
Created June 7, 2018 02:54
Show Gist options
  • Save earlephilhower/405b6675048a93ac85f39a2ab19704fa to your computer and use it in GitHub Desktop.
Save earlephilhower/405b6675048a93ac85f39a2ab19704fa to your computer and use it in GitHub Desktop.
CertStoreFile as template
#include <Arduino.h>
#include <FS.h>
#include <BearSSLHelpers.h>
#include <bearssl/bearssl.h>
// Base class for the certificate stores, which allow use
// of a large set of certificates stored on SPIFFS of SD card to
// be dynamically used when validating a X509 certificate
class SDClass; // Just define it exists elsewhere to avoid including SD.h
namespace BearSSL {
template <typename FSType>
struct FSTraits;
template <>
struct FSTraits<fs::FS>
{
static const char *modeRead() { return "r"; }
static const char *modeWrite() { return "w"; }
static SeekMode seekSet() { return SeekSet; }
};
template <>
struct FSTraits<::SDClass>
{
static int modeRead() { return 0x01; }
static int modeWrite() { return 0x13; }
static int seekSet() { return 0; }
};
template <typename FSType>
class CertStoreFile {
public:
CertStoreFile(FSType &fs, const char *name) : _fs(fs), _name(name) {};
virtual ~CertStoreFile() {};
// The main API
bool open(bool write = false) {
_file = _fs->open(_name, write ? FSTraits<FSType>::modeWrite() : FSTraits<FSType>::modeRead() );
return _file;
}
bool seek(size_t absolute_pos) {
return _file.seek(absolute_pos, FSTraits<FSType>::seekSet());
}
ssize_t read(void *dest, size_t bytes) {
return _file.readBytes( (char *)dest, bytes);
}
ssize_t write(void *dest, size_t bytes) {
return _file.write( (char*)dest, bytes);
}
void close() {
_file.close();
}
private:
FSType & _fs;
const char *_name;
typename FSTraits<FSType>::File _file;
};
template <typename FSType>
class CertStore {
public:
CertStore() { };
~CertStore() { };
// Set the file interface instances, do preprocessing
int initCertStore(CertStoreFile<FSType> *index, CertStoreFile<FSType> *data);
// Installs the cert store into the X509 decoder (normally via static function callbacks)
void installCertStore(br_x509_minimal_context *ctx);
protected:
CertStoreFile<FSType> *_index = nullptr;
CertStoreFile<FSType> *_data = nullptr;
BearSSLX509List *_x509 = nullptr;
// These need to be static as they are callbacks from BearSSL C code
static const br_x509_trust_anchor *findHashedTA(void *ctx, void *hashed_dn, size_t len);
static void freeHashedTA(void *ctx, const br_x509_trust_anchor *ta);
// The binary format of the index file
class CertInfo {
public:
uint8_t sha256[32];
uint32_t offset;
uint32_t length;
};
static CertInfo _preprocessCert(uint32_t length, uint32_t offset, const void *raw);
};
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment