diff options
Diffstat (limited to 'eap_tls_common.c')
-rw-r--r-- | eap_tls_common.c | 81 |
1 files changed, 58 insertions, 23 deletions
diff --git a/eap_tls_common.c b/eap_tls_common.c index a3ed594..de17886 100644 --- a/eap_tls_common.c +++ b/eap_tls_common.c @@ -28,25 +28,26 @@ #include <openssl/x509v3.h> #include <keystore_get.h> -#define PEM_CERT_HEADER "-----BEGIN CERTIFICATE-----" +#define PEM_CERT_KEYWORD "CERTIFICATE" +#define PEM_PRIVATEKEY_KEYWORD "PRIVATE KEY" -struct cache_blobs { - struct cache_blobs *next; +struct temporal_blobs { + struct temporal_blobs *next; struct wpa_config_blob *blob; }; -static struct cache_blobs *ks_blobs = NULL; +static struct temporal_blobs *ks_blobs = NULL; /** * The blob data can not be inserted into config->blobs structure, since the * protected cert/key may be rewritten to config file. We have to maintain the * keystore-only blobs. */ -static int add_cache_blob(struct wpa_config_blob *blob) +static int add_temporal_blob(struct wpa_config_blob *blob) { - struct cache_blobs *p; + struct temporal_blobs *p; - p = (struct cache_blobs*) malloc(sizeof(struct cache_blobs)); + p = (struct temporal_blobs*) malloc(sizeof(struct temporal_blobs)); if (p == NULL) { return -1; } @@ -56,18 +57,46 @@ static int add_cache_blob(struct wpa_config_blob *blob) return 0; } -static struct wpa_config_blob *get_cache_blob(const char *name) +static void free_temporal_blobs() { - struct cache_blobs *p = ks_blobs; + struct temporal_blobs *p = ks_blobs; - if (name != NULL) { - while (p != NULL) { - if (os_strcmp(p->blob->name, name) == 0) - return p->blob; - p = p->next; - } + while (p != NULL) { + struct temporal_blobs *q = p; + p = p->next; + if (q->blob) free(q->blob); + free(q); } - return NULL; + ks_blobs = NULL; +} + +typedef enum { + PEM_CERTIFICATE, + PEM_PRIVATE_KEY, + DER_FORMAT, + UNKNOWN_CERT_TYPE +} CERT_TYPE; + +/** + * Tell the encoding format and type of the certificate/key by examining if + * there is "CERTIFICATE" or "PRIVATE KEY" in the blob. If not, at least we + * can test if the first byte is '0'. + */ +static CERT_TYPE get_blob_type(struct wpa_config_blob *blob) +{ + CERT_TYPE type = UNKNOWN_CERT_TYPE; + unsigned char p = blob->data[blob->len - 1]; + + blob->data[blob->len - 1] = 0; + if (strstr(blob->data, PEM_CERT_KEYWORD) != NULL) { + type = PEM_CERTIFICATE; + } else if (strstr(blob->data, PEM_PRIVATEKEY_KEYWORD) != NULL) { + type = PEM_PRIVATE_KEY; + } else if (blob->data[0] == '0') { + type = DER_FORMAT; + } + blob->data[blob->len - 1] = p; + return type; } /** @@ -82,15 +111,21 @@ static void convert_PEM_to_DER(struct wpa_config_blob *blob) BIO *bp = NULL; unsigned char *buf = NULL; int len = 0; + CERT_TYPE type; + + if (blob->len < sizeof(PEM_CERT_KEYWORD)) { + return; + } - if (blob->len < sizeof(PEM_CERT_HEADER) || blob->data[0] != '-') + if (((type = get_blob_type(blob)) != PEM_CERTIFICATE) && + (type != PEM_PRIVATE_KEY)) { return; + } bp = BIO_new(BIO_s_mem()); if (!bp) goto err; if (!BIO_write(bp, blob->data, blob->len)) goto err; - if (memcmp((char*)blob->data, PEM_CERT_HEADER, - strlen(PEM_CERT_HEADER)) == 0) { + if (type == PEM_CERTIFICATE) { if ((cert = PEM_read_bio_X509(bp, NULL, NULL, NULL)) != NULL) { len = i2d_X509(cert, &buf); } @@ -117,9 +152,6 @@ struct wpa_config_blob *get_blob_from_keystore(const char *name) char *buf = keystore_get((char*)name, &len); struct wpa_config_blob *blob = NULL; - if ((blob = get_cache_blob(name)) != NULL) { - return blob; - } if (buf) { if ((blob = os_zalloc(sizeof(*blob))) != NULL) { blob->name = os_strdup(name); @@ -131,7 +163,7 @@ struct wpa_config_blob *get_blob_from_keystore(const char *name) } if (blob) { convert_PEM_to_DER(blob); - add_cache_blob(blob); + add_temporal_blob(blob); } return blob; } @@ -314,6 +346,9 @@ int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, ret = 0; done: +#ifdef ANDROID + free_temporal_blobs(); +#endif return ret; } |