/** * @brief * Decode a base64-encoded string without any padding characters and return * the result. * @param buf * a pointer to a buffer containing the data to be decoded. * @param len * the length, in bytes, of the buffer to be decoded. * @param outlen * a pointer to a variable to receive the length of the decoded data. * @return * a pointer to a newly allocated buffer containing the base64-decoded, or * NULL on failure. * @free_using{free} */ unsigned char * _b64decode_nopad(char const *buf, size_t len, size_t *outlen) { unsigned char *result; char *padded; size_t padlen; if (!buf || !len || !outlen) { RET_ERROR_PTR(ERR_BAD_PARAM, NULL); } if (!(len % 4)) { return (_b64decode(buf, len, outlen)); } padlen = (len + 4) & ~(3); if (!(padded = malloc(padlen + 1))) { PUSH_ERROR_SYSCALL("malloc"); RET_ERROR_PTR(ERR_NOMEM, "could not allocate space for temporary string"); } memset(padded, '=', padlen); padded[padlen] = 0; memcpy(padded, buf, len); result = _b64decode(padded, padlen, outlen); free(padded); return result; }
/** * @brief * Load an EC public key from a file. * @param filename * the name of the file from which the key should be loaded * @return * a pointer to the deserialized public key from the the file. */ EC_KEY * _load_ec_pubkey(char const *filename) { char *filedata; unsigned char *bin; size_t binsize; EC_KEY *result; if (!filename) { RET_ERROR_PTR(ERR_BAD_PARAM, NULL); } if (!(filedata = _read_pem_data(filename, "PUBLIC KEY", 1))) { RET_ERROR_PTR(ERR_UNSPEC, "could not read ec pubkey pem file"); } bin = _b64decode(filedata, strlen(filedata), &binsize); _secure_wipe(filedata, strlen(filedata)); free(filedata); if (!bin) { RET_ERROR_PTR(ERR_UNSPEC, "could not decode b64 data"); } result = _deserialize_ec_pubkey(bin, binsize); _secure_wipe(bin, binsize); free(bin); if (!result) { RET_ERROR_PTR(ERR_UNSPEC, "could not deserialize binary ec pubkey"); } return result; }
/** * @brief * Load an ed25519 private key from a file. * @param filename * the path of the armored file from which the ed25519 private key will be * loaded. * @return * a pointer to a newly allocated ed25519 keypair on success, or NULL on * failure. */ ED25519_KEY * _load_ed25519_privkey(char const *filename) { ED25519_KEY *result; unsigned char *keydata; char *pemdata; size_t klen; if (!filename) { RET_ERROR_PTR(ERR_BAD_PARAM, NULL); } if (!(pemdata = _read_pem_data(filename, "ED25519 PRIVATE KEY", 1))) { RET_ERROR_PTR(ERR_UNSPEC, "unable to read ed25519 private key data from PEM file"); } keydata = _b64decode(pemdata, strlen(pemdata), &klen); _secure_wipe(pemdata, strlen(pemdata)); free(pemdata); if (!keydata || (klen != ED25519_KEY_SIZE)) { if (keydata) { _secure_wipe(keydata, klen); free(keydata); } RET_ERROR_PTR(ERR_UNSPEC, "bad ED25519 key data was read from file"); } if (!(result = malloc(sizeof(ED25519_KEY)))) { PUSH_ERROR_SYSCALL("malloc"); _secure_wipe(keydata, klen); free(keydata); RET_ERROR_PTR(ERR_NOMEM, "unable to allocate space for ED25519 key"); } memset(result, 0, sizeof(ED25519_KEY)); memcpy(result->private_key, keydata, sizeof(result->private_key)); _secure_wipe(keydata, klen); free(keydata); ed25519_publickey_donna(result->private_key, result->public_key); return result; }
/** * @brief Retrieves the keys binary from the keys file. * @param filename Null terminated string containing specified filename. * @param len Pointer to the length of the output. * @return Pointer to the keys binary string, this memory needs to be wipe before being freed. NULL on error. * @free_using{free} */ static unsigned char *keys_file_serialize(const char *filename, size_t *len) { char *b64_keys = NULL; unsigned char *serial_keys = NULL; if(!filename || !len) { RET_ERROR_PTR(ERR_BAD_PARAM, NULL); } if(!(b64_keys = _read_pem_data(filename, SIGNET_PRIVATE_KEYCHAIN, 1))) { RET_ERROR_PTR(ERR_UNSPEC, "could not retrieve keys from PEM file"); } if(!(serial_keys = _b64decode(b64_keys, strlen(b64_keys), len))) { free(b64_keys); RET_ERROR_PTR(ERR_UNSPEC, "could not base64 decode the keys"); } free(b64_keys); return serial_keys; }