aboutsummaryrefslogtreecommitdiff
path: root/eap_tls_common.c
diff options
context:
space:
mode:
authorChung-yih Wang <cywang@google.com>2009-07-14 16:42:36 +0800
committerChung-yih Wang <cywang@google.com>2009-07-14 17:15:11 +0800
commit8b41a26668d2f3dfe5a40893eefcdeece0bf7bbd (patch)
tree4016b4c24e8ddbdba945226826cd5c43540f9ff2 /eap_tls_common.c
parent696bb1baf94db908e4982d870c14e5d5600ac898 (diff)
downloadwpa_supplicant-8b41a26668d2f3dfe5a40893eefcdeece0bf7bbd.tar.gz
Fix the incorrect conversion detection in PEM format.
Since there could be some human readble help text in the PEM header, we need to refine our type checking to make it correct since tls_openssl can accept blob with DER format only. + The keystore blobs will be cleaned up for each tls connection.
Diffstat (limited to 'eap_tls_common.c')
-rw-r--r--eap_tls_common.c81
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;
}