23
23
#include "tls.h"
24
24
#include "config.h"
25
25
26
+ #ifdef ANDROID
27
+ #include <openssl/pem.h>
28
+ #include <openssl/x509v3.h>
29
+ #include <keystore_get.h>
30
+
31
+ #define PEM_CERT_HEADER "-----BEGIN CERTIFICATE-----"
32
+
33
+ struct cache_blobs {
34
+ struct cache_blobs * next ;
35
+ struct wpa_config_blob * blob ;
36
+ };
37
+
38
+ static struct cache_blobs * ks_blobs = NULL ;
39
+
40
+ /**
41
+ * The blob data can not be inserted into config->blobs structure, since the
42
+ * protected cert/key may be rewritten to config file. We have to maintain the
43
+ * keystore-only blobs.
44
+ */
45
+ static int add_cache_blob (struct wpa_config_blob * blob )
46
+ {
47
+ struct cache_blobs * p ;
48
+
49
+ p = (struct cache_blobs * ) malloc (sizeof (struct cache_blobs ));
50
+ if (p == NULL ) {
51
+ return -1 ;
52
+ }
53
+ p -> next = ks_blobs ;
54
+ p -> blob = blob ;
55
+ ks_blobs = p ;
56
+ return 0 ;
57
+ }
58
+
59
+ static struct wpa_config_blob * get_cache_blob (const char * name )
60
+ {
61
+ struct cache_blobs * p = ks_blobs ;
62
+
63
+ if (name != NULL ) {
64
+ while (p != NULL ) {
65
+ if (os_strcmp (p -> blob -> name , name ) == 0 )
66
+ return p -> blob ;
67
+ p = p -> next ;
68
+ }
69
+ }
70
+ return NULL ;
71
+ }
72
+
73
+ /**
74
+ * convert_PEM_to_DER() provides the converion from PEM format to DER one, since
75
+ * original certificate handling does not accept the PEM format for blob data.
76
+ * Therefore, we need to convert the data to DER format if it is PEM-format.
77
+ */
78
+ static void convert_PEM_to_DER (struct wpa_config_blob * blob )
79
+ {
80
+ X509 * cert = NULL ;
81
+ EVP_PKEY * pkey = NULL ;
82
+ BIO * bp = NULL ;
83
+ unsigned char * buf = NULL ;
84
+ int len = 0 ;
85
+
86
+ if (blob -> len < sizeof (PEM_CERT_HEADER ) || blob -> data [0 ] != '-' )
87
+ return ;
88
+
89
+ bp = BIO_new (BIO_s_mem ());
90
+ if (!bp ) goto err ;
91
+ if (!BIO_write (bp , blob -> data , blob -> len )) goto err ;
92
+ if (memcmp ((char * )blob -> data , PEM_CERT_HEADER ,
93
+ strlen (PEM_CERT_HEADER )) == 0 ) {
94
+ if ((cert = PEM_read_bio_X509 (bp , NULL , NULL , NULL )) != NULL ) {
95
+ len = i2d_X509 (cert , & buf );
96
+ }
97
+ } else {
98
+ if ((pkey = PEM_read_bio_PrivateKey (bp , NULL , NULL , NULL )) != NULL ) {
99
+ len = i2d_PrivateKey (pkey , & buf );
100
+ }
101
+ }
102
+
103
+ err :
104
+ if (bp ) BIO_free (bp );
105
+ if (cert ) X509_free (cert );
106
+ if (pkey ) EVP_PKEY_free (pkey );
107
+ if (buf ) {
108
+ free (blob -> data );
109
+ blob -> data = buf ;
110
+ blob -> len = len ;
111
+ }
112
+ }
113
+
114
+ struct wpa_config_blob * get_blob_from_keystore (const char * name )
115
+ {
116
+ int len ;
117
+ char * buf = keystore_get ((char * )name , & len );
118
+ struct wpa_config_blob * blob = NULL ;
119
+
120
+ if ((blob = get_cache_blob (name )) != NULL ) {
121
+ return blob ;
122
+ }
123
+ if (buf ) {
124
+ if ((blob = os_zalloc (sizeof (* blob ))) != NULL ) {
125
+ blob -> name = os_strdup (name );
126
+ blob -> data = (unsigned char * )buf ;
127
+ blob -> len = len ;
128
+ } else {
129
+ free (buf );
130
+ }
131
+ }
132
+ if (blob ) {
133
+ convert_PEM_to_DER (blob );
134
+ add_cache_blob (blob );
135
+ }
136
+ return blob ;
137
+ }
138
+ #endif
26
139
27
140
static int eap_tls_check_blob (struct eap_sm * sm , const char * * name ,
28
141
const u8 * * data , size_t * data_len )
@@ -33,12 +146,16 @@ static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
33
146
return 0 ;
34
147
35
148
blob = eap_get_config_blob (sm , * name + 7 );
149
+ #ifdef ANDROID
150
+ if (blob == NULL ) {
151
+ blob = get_blob_from_keystore (* name + 7 );
152
+ }
153
+ #endif
36
154
if (blob == NULL ) {
37
155
wpa_printf (MSG_ERROR , "%s: Named configuration blob '%s' not "
38
156
"found" , __func__ , * name + 7 );
39
157
return -1 ;
40
158
}
41
-
42
159
* name = NULL ;
43
160
* data = blob -> data ;
44
161
* data_len = blob -> len ;
0 commit comments