1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "auth.h"
16 #include <openssl/evp.h>
17 #include <openssl/objects.h>
18 #include <openssl/pem.h>
19 #include <openssl/rsa.h>
20 #include <openssl/sha.h>
21 #include <openssl/err.h>
22 #include <fstream>
23 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
24 #include "password.h"
25 #endif
26
27 using namespace Hdc;
28 #define BIGNUMTOBIT 32
29
30 namespace HdcAuth {
31 // ---------------------------------------Cheat compiler---------------------------------------------------------
32 #ifdef HDC_HOST
33
AuthVerify(uint8_t * token,uint8_t * sig,int siglen)34 bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen)
35 {
36 return false;
37 };
PostUIConfirm(string publicKey)38 bool PostUIConfirm(string publicKey)
39 {
40 return false;
41 }
42
43 #else // daemon
44
45 bool GenerateKey(const char *file)
46 {
47 return false;
48 };
49 int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig)
50 {
51 return 0;
52 };
53 int GetPublicKeyFileBuf(unsigned char *data, size_t len)
54 {
55 return 0;
56 }
57
58 #endif
59 // ------------------------------------------------------------------------------------------------
60
61 const uint32_t RSANUMBYTES = 512; // 4096 bit key length
62 const uint32_t RSANUMWORDS = (RSANUMBYTES / sizeof(uint32_t));
63 struct RSAPublicKey {
64 int wordModulusSize; // Length of n[] in number of uint32_t */
65 uint32_t rsaN0inv; // -1 / n[0] mod 2^32
66 uint32_t modulus[RSANUMWORDS]; // modulus as little endian array
67 uint32_t rr[RSANUMWORDS]; // R^2 as little endian array
68 BN_ULONG exponent; // 3 or 65537
69 };
70
71 #ifdef HDC_HOST
72 // Convert OpenSSL RSA private key to pre-computed RSAPublicKey format
RSA2RSAPublicKey(RSA * rsa,RSAPublicKey * publicKey)73 int RSA2RSAPublicKey(RSA *rsa, RSAPublicKey *publicKey)
74 {
75 int result = 1;
76 unsigned int i;
77 BN_CTX *ctx = BN_CTX_new();
78 BIGNUM *r32 = BN_new();
79 BIGNUM *rsaRR = BN_new();
80 BIGNUM *rsaR = BN_new();
81 BIGNUM *rsaRem = BN_new();
82 BIGNUM *rsaN0inv = BN_new();
83 #ifdef OPENSSL_IS_BORINGSSL
84 // boringssl
85 BIGNUM *n = BN_new();
86 BN_copy(n, rsa->n);
87 publicKey->exponent = BN_get_word(rsa->e);
88 #else
89 // openssl
90 #if OPENSSL_VERSION_NUMBER >= 0x10100005L
91 BIGNUM *n = (BIGNUM *)RSA_get0_n(rsa);
92 publicKey->exponent = BN_get_word(RSA_get0_e(rsa));
93 #else
94 BIGNUM *n = BN_new();
95 BN_copy(n, rsa->n);
96 publicKey->exponent = BN_get_word(rsa->e);
97 #endif
98
99 #endif // OPENSSL_IS_BORINGSSL
100 while (true) {
101 if (RSA_size(rsa) != RSANUMBYTES) {
102 result = 0;
103 break;
104 }
105
106 BN_set_bit(r32, BIGNUMTOBIT);
107 BN_set_bit(rsaR, RSANUMWORDS * BIGNUMTOBIT);
108 BN_mod_sqr(rsaRR, rsaR, n, ctx);
109 BN_div(nullptr, rsaRem, n, r32, ctx);
110 BN_mod_inverse(rsaN0inv, rsaRem, r32, ctx);
111 publicKey->wordModulusSize = RSANUMWORDS;
112 publicKey->rsaN0inv = 0 - BN_get_word(rsaN0inv);
113 for (i = 0; i < RSANUMWORDS; ++i) {
114 BN_div(rsaRR, rsaRem, rsaRR, r32, ctx);
115 publicKey->rr[i] = BN_get_word(rsaRem);
116 BN_div(n, rsaRem, n, r32, ctx);
117 publicKey->modulus[i] = BN_get_word(rsaRem);
118 }
119 break;
120 }
121
122 BN_free(rsaR);
123 BN_free(rsaRR);
124 BN_free(n);
125 BN_free(r32);
126 BN_free(rsaN0inv);
127 BN_free(rsaRem);
128 BN_CTX_free(ctx);
129 return result;
130 }
131
GetUserInfo(char * buf,size_t len)132 int GetUserInfo(char *buf, size_t len)
133 {
134 char hostname[BUF_SIZE_DEFAULT];
135 char username[BUF_SIZE_DEFAULT];
136 uv_passwd_t pwd;
137 int ret = -1;
138 size_t bufSize = sizeof(hostname);
139 if (uv_os_gethostname(hostname, &bufSize) < 0 && EOK != strcpy_s(hostname, sizeof(hostname), "unknown")) {
140 return ERR_API_FAIL;
141 }
142 if (!uv_os_get_passwd(&pwd) && !strcpy_s(username, sizeof(username), pwd.username)) {
143 ret = 0;
144 }
145 uv_os_free_passwd(&pwd);
146 if (ret < 0 && EOK != strcpy_s(username, sizeof(username), "unknown")) {
147 return ERR_API_FAIL;
148 }
149 if (snprintf_s(buf, len, len - 1, " %s@%s", username, hostname) < 0) {
150 return ERR_BUF_OVERFLOW;
151 }
152 return RET_SUCCESS;
153 }
154
WritePublicKeyfile(RSA * private_key,const char * private_key_path)155 int WritePublicKeyfile(RSA *private_key, const char *private_key_path)
156 {
157 RSAPublicKey publicKey;
158 char info[BUF_SIZE_DEFAULT];
159 int ret = 0;
160 string path = private_key_path + string(".pub");
161
162 ret = RSA2RSAPublicKey(private_key, &publicKey);
163 if (!ret) {
164 WRITE_LOG(LOG_DEBUG, "Failed to convert to publickey\n");
165 return 0;
166 }
167 vector<uint8_t> vec = Base::Base64Encode((const uint8_t *)&publicKey, sizeof(RSAPublicKey));
168 if (!vec.size()) {
169 return 0;
170 }
171 GetUserInfo(info, sizeof(info));
172 vec.insert(vec.end(), (uint8_t *)info, (uint8_t *)info + strlen(info));
173 ret = Base::WriteBinFile(path.c_str(), vec.data(), vec.size(), true);
174 return ret >= 0 ? 1 : 0;
175 }
176
GenerateKey(const char * file)177 bool GenerateKey(const char *file)
178 {
179 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
180 Base::PrintMessage("[E002105] Unsupport command]");
181 return false;
182 #endif
183 EVP_PKEY *publicKey = EVP_PKEY_new();
184 BIGNUM *exponent = BN_new();
185 RSA *rsa = RSA_new();
186 int bits = 4096;
187 mode_t old_mask;
188 FILE *fKey = nullptr;
189 bool ret = false;
190
191 while (true) {
192 WRITE_LOG(LOG_DEBUG, "generate_key '%s'\n", file);
193 if (!publicKey || !exponent || !rsa) {
194 WRITE_LOG(LOG_DEBUG, "Failed to allocate key");
195 break;
196 }
197
198 BN_set_word(exponent, RSA_F4);
199 RSA_generate_key_ex(rsa, bits, exponent, nullptr);
200 EVP_PKEY_set1_RSA(publicKey, rsa);
201 old_mask = umask(077); // 077:permission
202
203 fKey = Base::Fopen(file, "w");
204 if (!fKey) {
205 WRITE_LOG(LOG_DEBUG, "Failed to open '%s'\n", file);
206 umask(old_mask);
207 break;
208 }
209 umask(old_mask);
210 if (!PEM_write_PrivateKey(fKey, publicKey, nullptr, nullptr, 0, nullptr, nullptr)) {
211 WRITE_LOG(LOG_DEBUG, "Failed to write key");
212 break;
213 }
214 if (!WritePublicKeyfile(rsa, file)) {
215 WRITE_LOG(LOG_DEBUG, "Failed to write public key");
216 break;
217 }
218 ret = true;
219 break;
220 }
221
222 EVP_PKEY_free(publicKey);
223 BN_free(exponent);
224 if (fKey)
225 fclose(fKey);
226 return ret;
227 }
228
ReadKey(const char * file,list<void * > * listPrivateKey)229 bool ReadKey(const char *file, list<void *> *listPrivateKey)
230 {
231 FILE *f = nullptr;
232 bool ret = false;
233
234 if (file == nullptr || listPrivateKey == nullptr) {
235 WRITE_LOG(LOG_FATAL, "file or listPrivateKey is null");
236 return ret;
237 }
238 while (true) {
239 if (!(f = fopen(file, "r"))) {
240 break;
241 }
242 RSA *rsa = RSA_new();
243 if (!PEM_read_RSAPrivateKey(f, &rsa, nullptr, nullptr)) {
244 RSA_free(rsa);
245 break;
246 }
247 listPrivateKey->push_back((void *)rsa);
248 ret = true;
249 break;
250 }
251 if (f) {
252 fclose(f);
253 }
254 return ret;
255 }
256
GetUserKeyPath(string & path)257 bool GetUserKeyPath(string &path)
258 {
259 struct stat status;
260 const char harmoneyPath[] = ".harmony";
261 const char hdcKeyFile[] = "hdckey";
262 char buf[BUF_SIZE_DEFAULT];
263 size_t len = BUF_SIZE_DEFAULT;
264 // $home
265 if (uv_os_homedir(buf, &len) < 0)
266 return false;
267 string dir = string(buf) + Base::GetPathSep() + string(harmoneyPath) + Base::GetPathSep();
268 path = Base::CanonicalizeSpecPath(dir);
269 if (path.empty()) {
270 path = dir;
271 } else {
272 path += Base::GetPathSep(); // bugfix for unix platform create key file not in dir.
273 }
274 if (stat(path.c_str(), &status)) {
275 uv_fs_t req;
276 uv_fs_mkdir(nullptr, &req, path.c_str(), 0750, nullptr); // 0750:permission
277 uv_fs_req_cleanup(&req);
278 uv_fs_stat(nullptr, &req, path.c_str(), nullptr);
279 uv_fs_req_cleanup(&req);
280 if (req.result < 0) {
281 WRITE_LOG(LOG_FATAL, "Cannot mkdir '%s'", path.c_str());
282 return false;
283 }
284 }
285 path += hdcKeyFile;
286 return true;
287 }
288
LoadHostUserKey(list<void * > * listPrivateKey)289 bool LoadHostUserKey(list<void *> *listPrivateKey)
290 {
291 struct stat status;
292 string path;
293 if (!GetUserKeyPath(path)) {
294 return false;
295 }
296 if (stat(path.c_str(), &status) == -1) {
297 if (!GenerateKey(path.c_str())) {
298 WRITE_LOG(LOG_DEBUG, "Failed to generate new key");
299 return false;
300 }
301 }
302 if (!ReadKey(path.c_str(), listPrivateKey)) {
303 return false;
304 }
305 return true;
306 }
307
AuthSign(void * rsa,const unsigned char * token,size_t tokenSize,void * sig)308 int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig)
309 {
310 unsigned int len;
311 if (!RSA_sign(NID_sha256, token, tokenSize, (unsigned char *)sig, &len, (RSA *)rsa)) {
312 return 0;
313 }
314 return static_cast<int>(len);
315 }
316
GetPublicKeyFileBuf(unsigned char * data,size_t len)317 int GetPublicKeyFileBuf(unsigned char *data, size_t len)
318 {
319 string path;
320 int ret;
321
322 if (!GetUserKeyPath(path)) {
323 return 0;
324 }
325 path += ".pub";
326 ret = Base::ReadBinFile(path.c_str(), (void **)data, len);
327 if (ret <= 0) {
328 return 0;
329 }
330 data[ret] = '\0';
331 return ret + 1;
332 }
333
334 #else // daemon
335
RSAPublicKey2RSA(const uint8_t * keyBuf,RSA ** key)336 bool RSAPublicKey2RSA(const uint8_t *keyBuf, RSA **key)
337 {
338 const int pubKeyModulusSize = 256;
339 const int pubKeyModulusSizeWords = pubKeyModulusSize / 4;
340
341 const RSAPublicKey *keyStruct = reinterpret_cast<const RSAPublicKey *>(keyBuf);
342 bool ret = false;
343 uint8_t modulusBuffer[pubKeyModulusSize];
344 RSA *newKey = RSA_new();
345 if (!newKey) {
346 goto cleanup;
347 }
348 if (keyStruct->wordModulusSize != pubKeyModulusSizeWords) {
349 goto cleanup;
350 }
351 if (memcpy_s(modulusBuffer, sizeof(modulusBuffer), keyStruct->modulus, sizeof(modulusBuffer)) != EOK) {
352 goto cleanup;
353 }
354 Base::ReverseBytes(modulusBuffer, sizeof(modulusBuffer));
355
356 #ifdef OPENSSL_IS_BORINGSSL
357 // boringssl
358 newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr);
359 newKey->e = BN_new();
360 if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) {
361 goto cleanup;
362 }
363 #else
364 // openssl
365 #if OPENSSL_VERSION_NUMBER >= 0x10100005L
366 RSA_set0_key(newKey, BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr), BN_new(), BN_new());
367 #else
368 newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr);
369 newKey->e = BN_new();
370 if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) {
371 goto cleanup;
372 }
373 #endif
374 #endif
375
376 *key = newKey;
377 ret = true;
378
379 cleanup:
380 if (!ret && newKey) {
381 RSA_free(newKey);
382 }
383 return ret;
384 }
385
ReadDaemonKeys(const char * file,list<void * > * listPublicKey)386 void ReadDaemonKeys(const char *file, list<void *> *listPublicKey)
387 {
388 char buf[BUF_SIZE_DEFAULT2] = { 0 };
389 char *sep = nullptr;
390 int ret;
391 FILE *f = Base::Fopen(file, "re");
392 if (!f) {
393 WRITE_LOG(LOG_DEBUG, "Can't open '%s'", file);
394 return;
395 }
396 while (fgets(buf, sizeof(buf), f)) {
397 RSAPublicKey *key = new RSAPublicKey();
398 if (!key) {
399 break;
400 }
401 sep = strpbrk(buf, " \t");
402 if (sep) {
403 *sep = '\0';
404 }
405 ret = Base::Base64DecodeBuf(reinterpret_cast<uint8_t *>(buf), strlen(buf), reinterpret_cast<uint8_t *>(key));
406 if (ret != sizeof(RSAPublicKey)) {
407 WRITE_LOG(LOG_DEBUG, "%s: Invalid base64 data ret=%d", file, ret);
408 delete key;
409 continue;
410 }
411
412 if (key->wordModulusSize != RSANUMWORDS) {
413 WRITE_LOG(LOG_DEBUG, "%s: Invalid key len %d\n", file, key->wordModulusSize);
414 delete key;
415 continue;
416 }
417 listPublicKey->push_back(key);
418 }
419 fclose(f);
420 }
421
AuthVerify(uint8_t * token,uint8_t * sig,int siglen)422 bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen)
423 {
424 list<void *> listPublicKey;
425 uint8_t authKeyIndex = 0;
426 void *ptr = nullptr;
427 int ret = 0;
428 int childRet = 0;
429 while (KeylistIncrement(&listPublicKey, authKeyIndex, &ptr)) {
430 RSA *rsa = nullptr;
431 if (!RSAPublicKey2RSA((const uint8_t *)ptr, &rsa)) {
432 break;
433 }
434 childRet = RSA_verify(NID_sha256, reinterpret_cast<const unsigned char *>(token),
435 RSA_TOKEN_SIZE, reinterpret_cast<const unsigned char *>(sig),
436 siglen, rsa);
437 RSA_free(rsa);
438 if (childRet) {
439 ret = 1;
440 break;
441 }
442 }
443 FreeKey(true, &listPublicKey);
444 return ret;
445 }
446
LoadDaemonKey(list<void * > * listPublicKey)447 void LoadDaemonKey(list<void *> *listPublicKey)
448 {
449 #ifdef HDC_PCDEBUG
450 char keyPaths[][BUF_SIZE_SMALL] = { "/root/.harmony/hdckey.pub" };
451 #else
452 char keyPaths[][BUF_SIZE_SMALL] = { "/data/service/el1/public/hdc/hdc_keys" };
453 #endif
454 int num = sizeof(keyPaths) / sizeof(keyPaths[0]);
455 struct stat buf;
456
457 for (int i = 0; i < num; ++i) {
458 char *p = keyPaths[i];
459 if (!stat(p, &buf)) {
460 WRITE_LOG(LOG_DEBUG, "Loading keys from '%s'", p);
461 ReadDaemonKeys(p, listPublicKey);
462 }
463 }
464 }
465
PostUIConfirm(string publicKey)466 bool PostUIConfirm(string publicKey)
467 {
468 // Because the Hi3516 development board has no UI support for the time being, all public keys are received and
469 // By default, the system UI will record the public key /data/misc/hdc/hdckey/data/misc/hdc/hdckey
470 return true;
471 }
472 #endif // HDC_HOST
473
474 // --------------------------------------common code------------------------------------------
KeylistIncrement(list<void * > * listKey,uint8_t & authKeyIndex,void ** out)475 bool KeylistIncrement(list<void *> *listKey, uint8_t &authKeyIndex, void **out)
476 {
477 if (!listKey->size()) {
478 #ifdef HDC_HOST
479 LoadHostUserKey(listKey);
480 #else
481 LoadDaemonKey(listKey);
482 #endif
483 }
484 if (authKeyIndex == listKey->size()) {
485 // all finish
486 return false;
487 }
488 auto listIndex = listKey->begin();
489 std::advance(listIndex, ++authKeyIndex);
490 *out = *listIndex;
491 if (!*out) {
492 return false;
493 }
494 return true;
495 }
496
FreeKey(bool publicOrPrivate,list<void * > * listKey)497 void FreeKey(bool publicOrPrivate, list<void *> *listKey)
498 {
499 for (auto &&v : *listKey) {
500 if (publicOrPrivate) {
501 delete (RSAPublicKey *)v;
502 v = nullptr;
503 } else {
504 RSA_free((RSA *)v);
505 v = nullptr;
506 }
507 }
508 listKey->clear();
509 }
510
511 #ifdef HDC_HOST
GenerateNewKey(void)512 EVP_PKEY *GenerateNewKey(void)
513 {
514 bool success = false;
515 int bits = RSA_KEY_BITS;
516 RSA *rsa = RSA_new();
517 BIGNUM *e = BN_new();
518 EVP_PKEY *evp = EVP_PKEY_new();
519
520 while (true) {
521 if (!evp || !e || !rsa) {
522 WRITE_LOG(LOG_FATAL, "allocate key failed");
523 break;
524 }
525
526 BN_set_word(e, RSA_F4);
527 if (!RSA_generate_key_ex(rsa, bits, e, nullptr)) {
528 WRITE_LOG(LOG_FATAL, "generate rsa key failed");
529 break;
530 }
531 if (!EVP_PKEY_set1_RSA(evp, rsa)) {
532 WRITE_LOG(LOG_FATAL, "evp set rsa failed");
533 break;
534 }
535
536 WRITE_LOG(LOG_INFO, "generate key pair success");
537 success = true;
538 break;
539 }
540
541 if (e)
542 BN_free(e);
543 if (success) {
544 return evp;
545 }
546
547 // if fail, need free rsa and evp
548 if (rsa)
549 RSA_free(rsa);
550 if (evp)
551 EVP_PKEY_free(evp);
552
553 return nullptr;
554 }
555
WritePublicFile(const std::string & fileName,EVP_PKEY * evp)556 static bool WritePublicFile(const std::string& fileName, EVP_PKEY *evp)
557 {
558 FILE *fp = nullptr;
559 fp = Base::Fopen(fileName.c_str(), "w");
560 if (fp == nullptr) {
561 WRITE_LOG(LOG_FATAL, "open %s failed", fileName.c_str());
562 return false;
563 }
564 if (!PEM_write_PUBKEY(fp, evp)) {
565 WRITE_LOG(LOG_FATAL, "write public key file %s failed", fileName.c_str());
566 (void)fclose(fp);
567 return false;
568 }
569 (void)fclose(fp);
570 return true;
571 }
572
573 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
WritePrivatePwdFile(const std::string & fileName,const std::string & encryptPwd)574 static bool WritePrivatePwdFile(const std::string& fileName, const std::string& encryptPwd)
575 {
576 return Base::WriteToFile(fileName, encryptPwd, std::ios::out | std::ios::trunc);
577 }
578 #endif
579
WritePrivateFile(const std::string & fileName,EVP_PKEY * evp)580 static bool WritePrivateFile(const std::string& fileName, EVP_PKEY *evp)
581 {
582 FILE *fp = nullptr;
583 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
584 Hdc::HdcPassword pwd(HDC_PRIVATE_KEY_FILE_PWD_KEY_ALIAS);
585 pwd.GeneratePassword();
586 if (!pwd.EncryptPwd()) {
587 WRITE_LOG(LOG_FATAL, "encrypt pwd failed");
588 return false;
589 }
590 std::pair<uint8_t*, int> pwdValue = pwd.GetPassword();
591 #endif
592 fp = Base::Fopen(fileName.c_str(), "w");
593 if (fp == nullptr) {
594 WRITE_LOG(LOG_FATAL, "open %s failed", fileName.c_str());
595 return false;
596 }
597 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
598 if (!PEM_write_PrivateKey(fp, evp, EVP_aes_256_cbc(), pwdValue.first, pwdValue.second, nullptr, nullptr)) {
599 #else
600 if (!PEM_write_PrivateKey(fp, evp, nullptr, nullptr, 0, nullptr, nullptr)) {
601 #endif
602 WRITE_LOG(LOG_FATAL, "write private key failed");
603 (void)fclose(fp);
604 return false;
605 }
606 (void)fclose(fp);
607 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
608 if (!WritePrivatePwdFile(fileName + ".key", pwd.GetEncryptPassword())) {
609 WRITE_LOG(LOG_FATAL, "write private key pwd failed");
610 return false;
611 }
612 #endif
613 return true;
614 }
615
616 bool GenerateKeyPair(const string& prikey_filename, const string& pubkey_filename)
617 {
618 bool ret = false;
619 EVP_PKEY *evp = nullptr;
620 #ifdef __OHOS__
621 mode_t old_mask = umask(027); // 027:permission
622 #else
623 mode_t old_mask = umask(077); // 077:permission
624 #endif
625
626 while (true) {
627 evp = GenerateNewKey();
628 if (!evp) {
629 WRITE_LOG(LOG_FATAL, "generate new key failed");
630 break;
631 }
632
633 if (!WritePublicFile(pubkey_filename, evp)) {
634 break;
635 }
636
637 if (!WritePrivateFile(prikey_filename, evp)) {
638 break;
639 }
640 WRITE_LOG(LOG_INFO, "generate key pair success");
641 ret = true;
642 break;
643 }
644
645 if (evp) {
646 EVP_PKEY_free(evp);
647 }
648 umask(old_mask);
649 return ret;
650 }
651
652 bool LoadPublicKey(const string& pubkey_filename, string &pubkey)
653 {
654 bool ret = false;
655 BIO *bio = nullptr;
656 EVP_PKEY *evp = nullptr;
657 FILE *file_pubkey = nullptr;
658
659 do {
660 file_pubkey = Base::Fopen(pubkey_filename.c_str(), "r");
661 if (!file_pubkey) {
662 WRITE_LOG(LOG_FATAL, "open file %s failed", pubkey_filename.c_str());
663 break;
664 }
665 evp = PEM_read_PUBKEY(file_pubkey, NULL, NULL, NULL);
666 if (!evp) {
667 WRITE_LOG(LOG_FATAL, "read pubkey from %s failed", pubkey_filename.c_str());
668 break;
669 }
670 bio = BIO_new(BIO_s_mem());
671 if (!bio) {
672 WRITE_LOG(LOG_FATAL, "alloc bio mem failed");
673 break;
674 }
675 if (!PEM_write_bio_PUBKEY(bio, evp)) {
676 WRITE_LOG(LOG_FATAL, "write bio failed");
677 break;
678 }
679 size_t len = 0;
680 char buf[RSA_KEY_BITS] = {0};
681 if (BIO_read_ex(bio, buf, sizeof(buf), &len) <= 0) {
682 WRITE_LOG(LOG_FATAL, "read bio failed");
683 break;
684 }
685 pubkey = string(buf, len);
686 ret = true;
687 WRITE_LOG(LOG_INFO, "load pubkey from file(%s) success", pubkey_filename.c_str());
688 } while (0);
689
690 if (evp) {
691 EVP_PKEY_free(evp);
692 evp = nullptr;
693 }
694 if (bio) {
695 BIO_free(bio);
696 bio = nullptr;
697 }
698 if (file_pubkey) {
699 fclose(file_pubkey);
700 file_pubkey = nullptr;
701 }
702 return ret;
703 }
704
705 bool TryLoadPublicKey(string &pubkey)
706 {
707 string prikey_filename;
708 struct stat status;
709 if (!GetUserKeyPath(prikey_filename)) {
710 WRITE_LOG(LOG_FATAL, "get key path failed");
711 return false;
712 }
713 string pubkey_filename = prikey_filename + ".pub";
714 #ifdef _WIN32
715 string prikeyFilenameWin = Base::UnicodeToUtf8(prikey_filename.c_str(), true);
716 if (stat(prikeyFilenameWin.c_str(), &status) == -1) {
717 #else
718 if (stat(prikey_filename.c_str(), &status) == -1) {
719 #endif
720 if (!GenerateKeyPair(prikey_filename, pubkey_filename)) {
721 WRITE_LOG(LOG_FATAL, "generate new key failed");
722 return false;
723 }
724 }
725 if (!LoadPublicKey(pubkey_filename, pubkey)) {
726 WRITE_LOG(LOG_FATAL, "load key failed");
727 return false;
728 }
729
730 WRITE_LOG(LOG_INFO, "load pubkey success");
731
732 return true;
733 }
734
735 bool GetHostName(string &hostname)
736 {
737 int ret;
738 char buf[BUF_SIZE_DEFAULT] = {0};
739 size_t bufsize = sizeof(buf);
740
741 ret = uv_os_gethostname(buf, &bufsize);
742 if (ret != 0) {
743 WRITE_LOG(LOG_FATAL, "get hostname failed: %d", ret);
744 return false;
745 }
746
747 hostname = string(buf, bufsize);
748
749 WRITE_LOG(LOG_INFO, "hostname: %s", hostname.c_str());
750
751 return true;
752 }
753
754 bool GetPublicKeyinfo(string &pubkey_info)
755 {
756 string hostname;
757 if (!GetHostName(hostname)) {
758 WRITE_LOG(LOG_FATAL, "gethostname failed");
759 return false;
760 }
761 string pubkey;
762 if (!HdcAuth::TryLoadPublicKey(pubkey)) {
763 WRITE_LOG(LOG_FATAL, "load public key failed");
764 return false;
765 }
766 pubkey_info = hostname;
767 pubkey_info.append(HDC_HOST_DAEMON_BUF_SEPARATOR);
768 pubkey_info.append(pubkey);
769
770 WRITE_LOG(LOG_INFO, "Get pubkey info success");
771
772 return true;
773 }
774
775 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
776 bool ReadEncryptKeyFile(const std::string& privateKeyFile, std::vector<uint8_t>& fileData, int needFileLength)
777 {
778 std::string privateKeyKeyFile = privateKeyFile + ".key";
779 std::ifstream inFile(privateKeyKeyFile.c_str(), std::ios::binary);
780 if (!inFile) {
781 WRITE_LOG(LOG_FATAL, "open file %s failed", privateKeyKeyFile.c_str());
782 return false;
783 }
784 fileData.resize(needFileLength);
785 inFile.read(reinterpret_cast<char*>(fileData.data()), needFileLength);
786 if (inFile.eof() || inFile.fail()) {
787 WRITE_LOG(LOG_FATAL, "read file %s failed", privateKeyKeyFile.c_str());
788 inFile.close();
789 return false;
790 }
791 inFile.close();
792 return true;
793 }
794
795 static uint8_t* GetPlainPwd(const std::string& privateKeyFile)
796 {
797 std::vector<uint8_t> encryptPwd;
798 Hdc::HdcPassword pwd(HDC_PRIVATE_KEY_FILE_PWD_KEY_ALIAS);
799
800 if (!ReadEncryptKeyFile(privateKeyFile, encryptPwd, pwd.GetEncryptPwdLength())) {
801 return nullptr;
802 }
803 if (!pwd.DecryptPwd(encryptPwd)) {
804 return nullptr;
805 }
806 std::pair<uint8_t*, int> plainPwd = pwd.GetPassword();
807 if (plainPwd.first == nullptr) {
808 return nullptr;
809 }
810 uint8_t *localPwd = new(std::nothrow)uint8_t[plainPwd.second + 1];
811 if (localPwd == nullptr) {
812 WRITE_LOG(LOG_FATAL, "out of mem %d", plainPwd.second);
813 return nullptr;
814 }
815 memcpy_s(localPwd, plainPwd.second, plainPwd.first, plainPwd.second);
816 localPwd[plainPwd.second] = '\0';
817 return localPwd;
818 }
819 #endif
820
821 static bool LoadPrivateKey(const string& prikey_filename, RSA **rsa, EVP_PKEY **evp)
822 {
823 FILE *file_prikey = nullptr;
824 bool ret = false;
825 *rsa = nullptr;
826 *evp = nullptr;
827 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
828 char *pwd = reinterpret_cast<char*>(GetPlainPwd(prikey_filename));
829 if (pwd == nullptr) {
830 return false;
831 }
832 #endif
833 do {
834 file_prikey = Base::Fopen(prikey_filename.c_str(), "r");
835 if (!file_prikey) {
836 WRITE_LOG(LOG_FATAL, "open file %s failed", prikey_filename.c_str());
837 break;
838 }
839 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
840 *evp = PEM_read_PrivateKey(file_prikey, NULL, NULL, pwd);
841 #else
842 *evp = PEM_read_PrivateKey(file_prikey, NULL, NULL, NULL);
843 #endif
844 if (*evp == nullptr) {
845 WRITE_LOG(LOG_FATAL, "read prikey from %s failed", prikey_filename.c_str());
846 break;
847 }
848 *rsa = EVP_PKEY_get1_RSA(*evp);
849 ret = true;
850 WRITE_LOG(LOG_FATAL, "load prikey success");
851 } while (0);
852
853 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
854 memset_s(pwd, strlen(pwd), 0, strlen(pwd));
855 delete[] pwd;
856 #endif
857 if (file_prikey) {
858 fclose(file_prikey);
859 file_prikey = nullptr;
860 }
861 return ret;
862 }
863
864 static bool MakeRsaSign(EVP_PKEY_CTX *ctx, string &result, unsigned char *digest, int digestLen)
865 {
866 size_t signResultLen = 0;
867 int signOutLen = 0;
868
869 // Determine the buffer length
870 if (EVP_PKEY_sign(ctx, nullptr, &signResultLen, digest, digestLen) <= 0) {
871 WRITE_LOG(LOG_FATAL, "get sign result length failed");
872 return false;
873 }
874 try {
875 std::unique_ptr<unsigned char[]> signResult = std::make_unique<unsigned char[]>(signResultLen);
876 std::unique_ptr<unsigned char[]> signOut = std::make_unique<unsigned char[]>(signResultLen * 2);
877 if (EVP_PKEY_sign(ctx, signResult.get(), &signResultLen, digest, digestLen) <=0) {
878 WRITE_LOG(LOG_FATAL, "sign failed");
879 return false;
880 }
881 signOutLen = EVP_EncodeBlock(signOut.get(), signResult.get(), signResultLen);
882 result = string(reinterpret_cast<char *>(signOut.get()), signOutLen);
883 } catch (std::exception &e) {
884 WRITE_LOG(LOG_FATAL, "sign failed for exception %s", e.what());
885 return false;
886 }
887
888 WRITE_LOG(LOG_INFO, "sign success");
889 return true;
890 }
891
892 static bool RsaSign(string &buf, EVP_PKEY *signKey)
893 {
894 unsigned char sha512Hash[SHA512_DIGEST_LENGTH];
895 EVP_PKEY_CTX *ctx = nullptr;
896 bool signRet = false;
897
898 do {
899 ctx = EVP_PKEY_CTX_new(signKey, nullptr);
900 if (ctx == nullptr) {
901 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
902 break;
903 }
904 if (EVP_PKEY_sign_init(ctx) <= 0) {
905 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
906 break;
907 }
908 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
909 EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST) <= 0) {
910 WRITE_LOG(LOG_FATAL, "set saltlen or padding failed");
911 break;
912 }
913 if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha512()) <= 0) {
914 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_set_signature_md failed");
915 break;
916 }
917 SHA512(reinterpret_cast<const unsigned char *>(buf.c_str()), buf.size(), sha512Hash);
918 signRet = MakeRsaSign(ctx, buf, sha512Hash, sizeof(sha512Hash));
919 } while (0);
920
921 if (ctx != nullptr) {
922 EVP_PKEY_CTX_free(ctx);
923 }
924 return signRet;
925 }
926
927 static bool RsaEncrypt(string &buf, RSA *rsa)
928 {
929 int signOriSize;
930 int signOutSize;
931 unsigned char signOri[BUF_SIZE_DEFAULT2] = { 0 };
932 unsigned char *signOut = nullptr;
933 int inSize = buf.size();
934 const unsigned char *in = reinterpret_cast<const unsigned char *>(buf.c_str());
935
936 signOriSize = RSA_private_encrypt(inSize, in, signOri, rsa, RSA_PKCS1_PADDING);
937 if (signOriSize <= 0) {
938 WRITE_LOG(LOG_FATAL, "encrypt failed");
939 return false;
940 }
941 signOut = new(std::nothrow) unsigned char[signOriSize * 2];
942 if (signOut == nullptr) {
943 WRITE_LOG(LOG_FATAL, "alloc mem failed");
944 return false;
945 }
946 signOutSize = EVP_EncodeBlock(signOut, signOri, signOriSize);
947 if (signOutSize <= 0) {
948 WRITE_LOG(LOG_FATAL, "encode buf failed");
949 delete[] signOut;
950 signOut = nullptr;
951 return false;
952 }
953
954 buf = string(reinterpret_cast<char *>(signOut), signOutSize);
955 WRITE_LOG(LOG_INFO, "sign success");
956 delete[] signOut;
957 signOut = nullptr;
958
959 return true;
960 }
961
962 bool RsaSignAndBase64(string &buf, AuthVerifyType type)
963 {
964 RSA *rsa = nullptr;
965 EVP_PKEY *evp = nullptr;
966 string prikeyFileName;
967 bool signResult = false;
968
969 if (!GetUserKeyPath(prikeyFileName)) {
970 WRITE_LOG(LOG_FATAL, "get key path failed");
971 return false;
972 }
973 if (!LoadPrivateKey(prikeyFileName, &rsa, &evp)) {
974 WRITE_LOG(LOG_FATAL, "load prikey from file(%s) failed", prikeyFileName.c_str());
975 return false;
976 }
977 if (type == AuthVerifyType::RSA_3072_SHA512) {
978 signResult = RsaSign(buf, evp);
979 } else {
980 signResult = RsaEncrypt(buf, rsa);
981 }
982 if (rsa != nullptr) {
983 RSA_free(rsa);
984 }
985 if (evp != nullptr) {
986 EVP_PKEY_free(evp);
987 }
988
989 return signResult;
990 }
991
992 int RsaPrikeyDecryptPsk(const unsigned char* in, int inLen, unsigned char* out, int outBufSize)
993 {
994 if (in == nullptr || out == nullptr) {
995 WRITE_LOG(LOG_FATAL, "RsaPrikeyDecryptPsk IO buf is alloc failed");
996 return -1;
997 }
998 if (inLen > BUF_SIZE_DEFAULT2 || inLen <= 0) {
999 WRITE_LOG(LOG_FATAL, "invalid encryptToken, length is %d", inLen);
1000 return -1;
1001 }
1002 if (outBufSize < PSK_MAX_PSK_LEN) {
1003 WRITE_LOG(LOG_FATAL, "out buffer is too small");
1004 return -1;
1005 }
1006 RSA *rsa = nullptr;
1007 EVP_PKEY *evp = nullptr;
1008 string prikeyFileName;
1009 int outLen = -1;
1010 do {
1011 if (!GetUserKeyPath(prikeyFileName)) {
1012 WRITE_LOG(LOG_FATAL, "get key path failed");
1013 break;
1014 }
1015 if (!LoadPrivateKey(prikeyFileName, &rsa, &evp)) {
1016 WRITE_LOG(LOG_FATAL, "load prikey from file(%s) failed", prikeyFileName.c_str());
1017 break;
1018 }
1019 unsigned char tokenDecode[BUF_SIZE_DEFAULT] = { 0 };
1020 int tbytes = EVP_DecodeBlock(tokenDecode, in, inLen);
1021 if (tbytes <= 0) {
1022 WRITE_LOG(LOG_FATAL, "base64 decode PreShared Key failed");
1023 break;
1024 }
1025 outLen = RSA_private_decrypt(tbytes, tokenDecode, out, rsa, RSA_PKCS1_OAEP_PADDING);
1026 if (outLen < 0) {
1027 WRITE_LOG(LOG_FATAL, "RSA_private_decrypt failed(%lu)", ERR_get_error());
1028 break;
1029 }
1030 } while (0);
1031 if (rsa != nullptr) {
1032 RSA_free(rsa);
1033 }
1034 if (evp != nullptr) {
1035 EVP_PKEY_free(evp);
1036 }
1037 return outLen;
1038 }
1039
1040 #ifdef HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
1041 int IsEncryptedPEM(const std::string& prikeyFileName)
1042 {
1043 if (prikeyFileName.empty()) {
1044 WRITE_LOG(LOG_FATAL, "private key file name is empty");
1045 return -1;
1046 }
1047
1048 FILE* filePrikey = Base::Fopen(prikeyFileName.c_str(), "r");
1049 if (filePrikey == nullptr) {
1050 WRITE_LOG(LOG_FATAL, "open private key file failed!error code: %d", strerror(errno));
1051 return 1; // file not exist or open failed
1052 }
1053
1054 char buf[BUF_SIZE_SMALL] = {0};
1055 int ret = 1;
1056 if (fgets(buf, sizeof(buf), filePrikey) != nullptr) {
1057 if (strncmp(buf, HDC_PRIVATE_KEY_FILE_FIRST_LINE_STR.c_str(),
1058 HDC_PRIVATE_KEY_FILE_FIRST_LINE_STR.size()) == 0) {
1059 WRITE_LOG(LOG_INFO, "private key is not encrypted, Re encrypt!");
1060 ret = 0; // not encrypted
1061 } else {
1062 WRITE_LOG(LOG_INFO, "private key is encrypted, not re encrypt!");
1063 ret = 1; // encrypted
1064 }
1065 }
1066
1067 if (fclose(filePrikey) != 0) {
1068 WRITE_LOG(LOG_FATAL, "fclose error:%d", strerror(errno));
1069 return -1;
1070 }
1071 return ret;
1072 }
1073 bool CheckPrivateKeyFile()
1074 {
1075 std::string prikeyFileName;
1076 if (!GetUserKeyPath(prikeyFileName)) {
1077 WRITE_LOG(LOG_FATAL, "get key path failed");
1078 return false;
1079 }
1080
1081 int ret = IsEncryptedPEM(prikeyFileName);
1082 if (ret == 0) {
1083 EVP_PKEY* evp = GenerateNewKey();
1084 if (evp == nullptr) {
1085 WRITE_LOG(LOG_FATAL, "generate new key failed");
1086 return false;
1087 }
1088 if (!WritePrivateFile(prikeyFileName, evp)) {
1089 WRITE_LOG(LOG_FATAL, "write private key failed");
1090 EVP_PKEY_free(evp);
1091 return false;
1092 }
1093 } else if (ret < 0) {
1094 WRITE_LOG(LOG_FATAL, "check private key file failed");
1095 return false;
1096 }
1097 return true;
1098 }
1099 #endif // HDC_SUPPORT_ENCRYPT_PRIVATE_KEY
1100
1101 #else // DAEMON
1102 int RsaPubkeyEncryptPsk(const unsigned char* in, int inLen, unsigned char* out, int outBufSize, const string& pubkey)
1103 {
1104 if (in == nullptr || out == nullptr) {
1105 WRITE_LOG(LOG_FATAL, "RsaPubkeyEncryptPsk IO buf is alloc failed");
1106 return -1;
1107 }
1108 BIO *bio = nullptr;
1109 RSA *rsa = nullptr;
1110 int outLen = -1;
1111 do {
1112 bio = BIO_new(BIO_s_mem());
1113 if (bio == nullptr) {
1114 WRITE_LOG(LOG_FATAL, "RsaPubkeyEncryptPsk create bio failed");
1115 break;
1116 }
1117 int wbytes = BIO_write(bio, reinterpret_cast<const unsigned char *>(pubkey.c_str()), pubkey.length());
1118 if (wbytes <= 0) {
1119 WRITE_LOG(LOG_FATAL, "RsaPubkeyEncryptPsk bio write failed %d ", wbytes);
1120 break;
1121 }
1122 rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr);
1123 if (rsa == nullptr) {
1124 WRITE_LOG(LOG_FATAL, "RsaPubkeyEncryptPsk rsa failed");
1125 break;
1126 }
1127 unsigned char encryptedBuf[BUF_SIZE_DEFAULT2] = { 0 };
1128 int encryptedBufSize = RSA_public_encrypt(inLen, in, encryptedBuf, rsa, RSA_PKCS1_OAEP_PADDING);
1129 if (encryptedBufSize <= 0 || (outBufSize < ((encryptedBufSize + 2) / 3 * 4))) { // (x+2)/3*4 base64 encode size
1130 WRITE_LOG(LOG_FATAL, "encrypt PreShared Key failed, encryptedBufSize: %d", encryptedBufSize);
1131 break;
1132 }
1133 outLen = EVP_EncodeBlock(out, encryptedBuf, encryptedBufSize);
1134 if (outLen <= 0) {
1135 WRITE_LOG(LOG_FATAL, "base64 encode PreShared Key failed");
1136 break;
1137 }
1138 } while (0);
1139
1140 if (bio != nullptr) {
1141 BIO_free(bio);
1142 }
1143 if (rsa != nullptr) {
1144 RSA_free(rsa);
1145 }
1146 return outLen;
1147 }
1148 #endif // HDC_HOST
1149 }
1150