7 #include <openssl/objects.h>
8 #include <openssl/rsa.h>
9 #include <openssl/sha.h>
23 #include "keys-gcrypt.c"
26 void *crda_get_file_ptr(__u8 *db, int dblen, int structlen, __be32 ptr)
30 if (p > dblen - structlen) {
31 fprintf(stderr, "Invalid database file, bad pointer!\n");
35 return (void *)(db + p);
39 * Checks the validity of the signature found on the regulatory
40 * database against the array 'keys'. Returns 1 if there exists
41 * at least one key in the array such that the signature is valid
42 * against that key; 0 otherwise.
44 int crda_verify_db_signature(__u8 *db, int dblen, int siglen)
48 __u8 hash[SHA_DIGEST_LENGTH];
54 fprintf(stderr, "Failed to create RSA key.\n");
58 if (SHA1(db, dblen, hash) != hash) {
59 fprintf(stderr, "Failed to calculate SHA1 sum.\n");
64 for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
68 if (RSA_size(rsa) != siglen)
71 ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
72 db + dblen, siglen, rsa) == 1;
81 gcry_mpi_t mpi_e, mpi_n;
82 gcry_sexp_t rsa, signature, data;
88 gcry_check_version(NULL);
91 gcry_md_hash_buffer(GCRY_MD_SHA1, hash, db, dblen);
93 if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
95 fprintf(stderr, "Failed to build data S-expression.\n");
99 if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
100 siglen, db + dblen)) {
101 fprintf(stderr, "Failed to build signature S-expression.\n");
105 for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
106 if (gcry_mpi_scan(&mpi_e, GCRYMPI_FMT_USG,
107 keys[i].e, keys[i].len_e, NULL) ||
108 gcry_mpi_scan(&mpi_n, GCRYMPI_FMT_USG,
109 keys[i].n, keys[i].len_n, NULL)) {
110 fprintf(stderr, "Failed to convert numbers.\n");
114 if (gcry_sexp_build(&rsa, NULL,
115 "(public-key (rsa (n %m) (e %m)))",
117 fprintf(stderr, "Failed to build RSA S-expression.\n");
121 ok = gcry_pk_verify(signature, data, rsa) == 0;
125 #if defined(USE_OPENSSL) || defined(USE_GCRYPT)
127 fprintf(stderr, "Database signature verification failed.\n");
136 void reg_rule2rd(__u8 *db, int dblen,
137 __be32 ruleptr, struct ieee80211_reg_rule *rd_reg_rule)
139 struct regdb_file_reg_rule *rule;
140 struct regdb_file_freq_range *freq;
141 struct regdb_file_power_rule *power;
143 struct ieee80211_freq_range *rd_freq_range = &rd_reg_rule->freq_range;
144 struct ieee80211_power_rule *rd_power_rule = &rd_reg_rule->power_rule;
146 rule = crda_get_file_ptr(db, dblen, sizeof(*rule), ruleptr);
147 freq = crda_get_file_ptr(db, dblen, sizeof(*freq), rule->freq_range_ptr);
148 power = crda_get_file_ptr(db, dblen, sizeof(*power), rule->power_rule_ptr);
150 rd_freq_range->start_freq_khz = ntohl(freq->start_freq);
151 rd_freq_range->end_freq_khz = ntohl(freq->end_freq);
152 rd_freq_range->max_bandwidth_khz = ntohl(freq->max_bandwidth);
154 rd_power_rule->max_antenna_gain = ntohl(power->max_antenna_gain);
155 rd_power_rule->max_eirp = ntohl(power->max_eirp);
157 rd_reg_rule->flags = ntohl(rule->flags);
160 /* Converts a file regdomain to ieee80211_regdomain, easier to manage */
161 struct ieee80211_regdomain *country2rd(__u8 *db, int dblen,
162 struct regdb_file_reg_country *country)
164 struct regdb_file_reg_rules_collection *rcoll;
165 struct ieee80211_regdomain *rd;
166 int i, num_rules, size_of_rd;
168 rcoll = crda_get_file_ptr(db, dblen, sizeof(*rcoll),
169 country->reg_collection_ptr);
170 num_rules = ntohl(rcoll->reg_rule_num);
171 /* re-get pointer with sanity checking for num_rules */
172 rcoll = crda_get_file_ptr(db, dblen,
173 sizeof(*rcoll) + num_rules * sizeof(__be32),
174 country->reg_collection_ptr);
176 size_of_rd = sizeof(struct ieee80211_regdomain) +
177 num_rules * sizeof(struct ieee80211_reg_rule);
179 rd = malloc(size_of_rd);
183 memset(rd, 0, size_of_rd);
185 rd->alpha2[0] = country->alpha2[0];
186 rd->alpha2[1] = country->alpha2[1];
187 rd->n_reg_rules = num_rules;
189 for (i = 0; i < num_rules; i++) {
190 reg_rule2rd(db, dblen, rcoll->reg_rule_ptrs[i],
197 /* Sanity check on a regulatory rule */
198 int is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
200 const struct ieee80211_freq_range *freq_range = &rule->freq_range;
203 if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
206 if (freq_range->start_freq_khz > freq_range->end_freq_khz)
209 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
211 if (freq_diff == 0 || freq_range->max_bandwidth_khz > freq_diff)
217 void print_reg_rule(struct ieee80211_reg_rule *rule)
219 struct ieee80211_freq_range *freq;
220 struct ieee80211_power_rule *power;
222 freq = &rule->freq_range;
223 power = &rule->power_rule;
225 printf("\t(%.3f - %.3f @ %.3f), ",
226 ((float)(freq->start_freq_khz))/1000.0,
227 ((float)(freq->end_freq_khz))/1000.0,
228 ((float)(freq->max_bandwidth_khz))/1000.0);
232 if (power->max_antenna_gain)
233 printf("%.2f, ", ((float)(power->max_antenna_gain)/100.0));
238 printf("%.2f)", ((float)(power->max_eirp)/100.0));
242 if (rule->flags & RRF_NO_OFDM)
244 if (rule->flags & RRF_NO_CCK)
246 if (rule->flags & RRF_NO_INDOOR)
247 printf(", NO-INDOOR");
248 if (rule->flags & RRF_NO_OUTDOOR)
249 printf(", NO-OUTDOOR");
250 if (rule->flags & RRF_DFS)
252 if (rule->flags & RRF_PTP_ONLY)
253 printf(", PTP-ONLY");
254 if (rule->flags & RRF_PTMP_ONLY)
255 printf(", PTMP-ONLY");
256 if (rule->flags & RRF_PASSIVE_SCAN)
257 printf(", PASSIVE-SCAN");
258 if (rule->flags & RRF_NO_IBSS)
264 void print_regdom(struct ieee80211_regdomain *rd)
267 printf("country %.2s:\n", rd->alpha2);
268 for (i = 0; i < rd->n_reg_rules; i++)
269 print_reg_rule(&rd->reg_rules[i]);