xref: /aosp_15_r20/external/wpa_supplicant_8/wpa_supplicant/aidl/vendor/misc_utils.h (revision 03f9172ca588f91df233974f4258bab95191f931)
1 /*
2  * WPA Supplicant - Helper methods for Aidl
3  * Copyright (c) 2021, Google Inc. All rights reserved.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #ifndef MISC_UTILS_H_
10 #define MISC_UTILS_H_
11 
12 #include <iostream>
13 #include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
14 
15 extern "C"
16 {
17 #include "wpabuf.h"
18 }
19 
20 namespace {
21 constexpr size_t kWpsPinNumDigits = 8;
22 // Custom deleter for wpabuf.
freeWpaBuf(wpabuf * ptr)23 void freeWpaBuf(wpabuf *ptr) { wpabuf_free(ptr); }
24 }  // namespace
25 
26 namespace aidl {
27 namespace android {
28 namespace hardware {
29 namespace wifi {
30 namespace supplicant {
31 namespace misc_utils {
32 using wpabuf_unique_ptr = std::unique_ptr<wpabuf, void (*)(wpabuf *)>;
33 
34 // Creates a unique_ptr for wpabuf ptr with a custom deleter.
createWpaBufUniquePtr(struct wpabuf * raw_ptr)35 inline wpabuf_unique_ptr createWpaBufUniquePtr(struct wpabuf *raw_ptr)
36 {
37 	return {raw_ptr, freeWpaBuf};
38 }
39 
40 // Creates a wpabuf ptr with a custom deleter copying the data from the provided
41 // vector.
convertVectorToWpaBuf(const std::vector<uint8_t> & data)42 inline wpabuf_unique_ptr convertVectorToWpaBuf(const std::vector<uint8_t> &data)
43 {
44 	return createWpaBufUniquePtr(
45 		wpabuf_alloc_copy(data.data(), data.size()));
46 }
47 
48 // Copies the provided wpabuf contents to a std::vector.
convertWpaBufToVector(const struct wpabuf * buf)49 inline std::vector<uint8_t> convertWpaBufToVector(const struct wpabuf *buf)
50 {
51 	if (buf) {
52 		return std::vector<uint8_t>(
53 			wpabuf_head_u8(buf), wpabuf_head_u8(buf) + wpabuf_len(buf));
54 	} else {
55 		return std::vector<uint8_t>();
56 	}
57 }
58 
59 // Returns a string holding the wps pin.
convertWpsPinToString(int pin)60 inline std::string convertWpsPinToString(int pin)
61 {
62 	char pin_str[kWpsPinNumDigits + 1];
63 	snprintf(pin_str, sizeof(pin_str), "%08d", pin);
64 	return pin_str;
65 }
66 
67 // Wrappers to create a ScopedAStatus using a SupplicantStatusCode
createStatus(SupplicantStatusCode status_code)68 inline ndk::ScopedAStatus createStatus(SupplicantStatusCode status_code) {
69 	return ndk::ScopedAStatus::fromServiceSpecificError(
70 		static_cast<int32_t>(status_code));
71 }
72 
createStatusWithMsg(SupplicantStatusCode status_code,std::string msg)73 inline ndk::ScopedAStatus createStatusWithMsg(
74 	SupplicantStatusCode status_code, std::string msg)
75 {
76 	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
77 		static_cast<int32_t>(status_code), msg.c_str());
78 }
79 
80 // Creates an std::string from a char*, which could be null
charBufToString(const char * buf)81 inline std::string charBufToString(const char* buf) {
82 	return buf ? std::string(buf) : "";
83 }
84 
serializePmkCacheEntry(std::stringstream & ss,struct rsn_pmksa_cache_entry * pmksa_entry)85 inline std::stringstream& serializePmkCacheEntry(
86 	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
87 	ss.write((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
88 	ss.write((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
89 	ss.write((char *) pmksa_entry->pmkid, PMKID_LEN);
90 	ss.write((char *) pmksa_entry->aa, ETH_ALEN);
91 	ss.write((char *) pmksa_entry->spa, ETH_ALEN);
92 	// Omit wpa_ssid field because the network is created on connecting to a access point.
93 	ss.write((char *) &pmksa_entry->akmp, sizeof(pmksa_entry->akmp));
94 	ss.write((char *) &pmksa_entry->reauth_time, sizeof(pmksa_entry->reauth_time));
95 	ss.write((char *) &pmksa_entry->expiration, sizeof(pmksa_entry->expiration));
96 	ss.write((char *) &pmksa_entry->opportunistic, sizeof(pmksa_entry->opportunistic));
97 	char byte = (pmksa_entry->fils_cache_id_set) ? 1 : 0;
98 	ss.write((char *) &byte, sizeof(byte));
99 	ss.write((char *) pmksa_entry->fils_cache_id, FILS_CACHE_ID_LEN);
100 	ss << std::flush;
101 	return ss;
102 }
103 
deserializePmkCacheEntry(std::stringstream & ss,struct rsn_pmksa_cache_entry * pmksa_entry)104 inline std::int8_t deserializePmkCacheEntry(
105 	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
106 	ss.seekg(0);
107 	if (ss.str().size() < sizeof(pmksa_entry->pmk_len)) {
108 		return -1;
109 	}
110 
111 	ss.read((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
112 	if ((pmksa_entry->pmk_len > PMK_LEN_MAX) ||
113 	    (ss.str().size() < (sizeof(pmksa_entry->pmk_len) + pmksa_entry->pmk_len +
114 	    PMKID_LEN + ETH_ALEN + ETH_ALEN + sizeof(pmksa_entry->akmp) +
115 	    sizeof(pmksa_entry->reauth_time) + sizeof(pmksa_entry->expiration) +
116 	    sizeof(pmksa_entry->opportunistic) + 1 /* fils_cache_id_set */)))
117 		return -1;
118 
119 	ss.read((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
120 	ss.read((char *) pmksa_entry->pmkid, PMKID_LEN);
121 	ss.read((char *) pmksa_entry->aa, ETH_ALEN);
122 	ss.read((char *) pmksa_entry->spa, ETH_ALEN);
123 	// Omit wpa_ssid field because the network is created on connecting to a access point.
124 	ss.read((char *) &pmksa_entry->akmp, sizeof(pmksa_entry->akmp));
125 	ss.read((char *) &pmksa_entry->reauth_time, sizeof(pmksa_entry->reauth_time));
126 	ss.read((char *) &pmksa_entry->expiration, sizeof(pmksa_entry->expiration));
127 	ss.read((char *) &pmksa_entry->opportunistic, sizeof(pmksa_entry->opportunistic));
128 	char byte = 0;
129 	ss.read((char *) &byte, sizeof(byte));
130 	pmksa_entry->fils_cache_id_set = (byte) ? 1 : 0;
131 	if (pmksa_entry->fils_cache_id_set == 1) {
132 		if((ss.str().size() - static_cast<uint32_t>(ss.tellg())) < FILS_CACHE_ID_LEN)
133 			return -1;
134 	}
135 
136 	ss.read((char *) pmksa_entry->fils_cache_id, FILS_CACHE_ID_LEN);
137 	return 0;
138 }
139 }  // namespace misc_utils
140 }  // namespace supplicant
141 }  // namespace wifi
142 }  // namespace hardware
143 }  // namespace android
144 }  // namespace aidl
145 #endif  // MISC_UTILS_H_
146