Merge pull request #512 from didishe90/persistSerDir
Persistent service directory
diff --git a/src/tools/weave/Cmd_GenCACert.cpp b/src/tools/weave/Cmd_GenCACert.cpp
index 38a1516..e733dfd 100644
--- a/src/tools/weave/Cmd_GenCACert.cpp
+++ b/src/tools/weave/Cmd_GenCACert.cpp
@@ -65,8 +65,9 @@
"\n"
" -k, --key <file>\n"
"\n"
- " File containing the public and private keys for the new CA certificate.\n"
- " (File must be in PEM format).\n"
+ " File containing the public key for the new CA certificate. The file may\n"
+ " contain only a public key, or a private key (from which the public key\n"
+ " can be obtained). The file must be in PEM or DER format.\n"
"\n"
" -C, --ca-cert <file>\n"
"\n"
@@ -76,7 +77,7 @@
" -K, --ca-key <file>\n"
"\n"
" File containing CA private key to be used to sign the new CA certificate.\n"
- " This file must be in PEM format.\n"
+ " This file may be in PEM or DER format.\n"
"\n"
" -o, --out <file>\n"
"\n"
@@ -245,7 +246,7 @@
else
newCertFile = stdout;
- if (!ReadPrivateKey(gNewCertKeyFileName, "Enter password for private key:", newCertKey))
+ if (!ReadPublicKey(gNewCertKeyFileName, "Enter password for private key:", newCertKey))
ExitNow(res = false);
if (!gSelfSign)
diff --git a/src/tools/weave/KeyUtils.cpp b/src/tools/weave/KeyUtils.cpp
index b327f7d..caedb59 100644
--- a/src/tools/weave/KeyUtils.cpp
+++ b/src/tools/weave/KeyUtils.cpp
@@ -186,8 +186,10 @@
if (keyFormat == kKeyFormat_Weave_Base64)
{
tmpKeyBuf = Base64Decode(keyData, keyDataLen, NULL, 0, keyDataLen);
- if (tmpKeyBuf == NULL)
- goto exit;
+ if (tmpKeyBuf == NULL) {
+ fprintf(stderr, "Base64 decoding error\n");
+ ExitNow(res = false);
+ }
keyData = tmpKeyBuf;
keyFormat = kKeyFormat_Weave_Raw;
}
@@ -620,3 +622,101 @@
}
return res;
}
+
+bool ReadPublicKey(const char *fileName, const char *prompt, EVP_PKEY *& key)
+{
+ bool res = true;
+ uint8_t *keyData = NULL;
+ uint32_t keyDataLen;
+
+ key = NULL;
+
+ res = ReadFileIntoMem(fileName, keyData, keyDataLen);
+ if (!res)
+ ExitNow();
+
+ res = DecodePublicKey(keyData, keyDataLen, kKeyFormat_Unknown, fileName, prompt, key);
+
+exit:
+ if (keyData != NULL)
+ free(keyData);
+ return res;
+}
+
+bool DecodePublicKeyOnly(const uint8_t *keyData, uint32_t keyDataLen, KeyFormat keyFormat, const char *keySource, EVP_PKEY *& key, bool noErrorOutput)
+{
+ bool res = true;
+ uint8_t *tmpKeyBuf = NULL;
+ BIO *keyBIO = NULL;
+
+ key = NULL;
+
+ if (keyFormat == kKeyFormat_Unknown)
+ {
+ keyFormat = DetectPublicKeyFormat(keyData, keyDataLen);
+ }
+
+ if (keyFormat != kKeyFormat_PEM && keyFormat != kKeyFormat_DER)
+ {
+ if (!noErrorOutput)
+ fprintf(stderr, "Unsupported public key format\n");
+ ExitNow(res = false);
+ }
+
+ keyBIO = BIO_new_mem_buf((void *)keyData, keyDataLen);
+ if (keyBIO == NULL)
+ {
+ if (!noErrorOutput)
+ fprintf(stderr, "Memory allocation error\n");
+ ExitNow(res = false);
+ }
+
+ if (keyFormat == kKeyFormat_PEM)
+ {
+ if (PEM_read_bio_PUBKEY(keyBIO, &key, NULL, NULL) == NULL)
+ {
+ if (!noErrorOutput) {
+ fprintf(stderr, "Unable to read %s\n", keySource);
+ ReportOpenSSLErrorAndExit("PEM_read_bio_PUBKEY", res = false);
+ }
+ ExitNow(res = false);
+ }
+ }
+ else
+ {
+ if (d2i_PUBKEY_bio(keyBIO, &key) == NULL)
+ {
+ if (!noErrorOutput) {
+ fprintf(stderr, "Unable to read %s\n", keySource);
+ ReportOpenSSLErrorAndExit("d2i_PUBKEY_bio", res = false);
+ }
+ ExitNow(res = false);
+ }
+ }
+
+exit:
+ if (tmpKeyBuf != NULL)
+ free(tmpKeyBuf);
+ if (keyBIO != NULL)
+ BIO_free_all(keyBIO);
+ return res;
+}
+
+bool DecodePublicKey(const uint8_t *keyData, uint32_t keyDataLen, KeyFormat keyFormat, const char *prompt, const char *keySource, EVP_PKEY *& key)
+{
+ bool res = true;
+ key = NULL;
+ res = DecodePublicKeyOnly(keyData, keyDataLen, keyFormat, keySource, key, true);
+ if (!res)
+ return DecodePrivateKey(keyData, keyDataLen, keyFormat, prompt, keySource, key);
+ return res;
+}
+
+KeyFormat DetectPublicKeyFormat(const uint8_t *key, uint32_t keyLen)
+{
+ static const char *publicKeyPEMMarker = "-----BEGIN PUBLIC KEY-----";
+
+ return ContainsPEMMarker(publicKeyPEMMarker, key, keyLen)
+ ? kKeyFormat_PEM
+ : kKeyFormat_DER;
+}
diff --git a/src/tools/weave/weave-tool.h b/src/tools/weave/weave-tool.h
index 6639bd7..e112966 100644
--- a/src/tools/weave/weave-tool.h
+++ b/src/tools/weave/weave-tool.h
@@ -132,6 +132,9 @@
extern bool EncodePrivateKey(EVP_PKEY *key, KeyFormat keyFormat, uint8_t *& encodedKey, uint32_t& encodedKeyLen);
extern bool WeaveEncodePrivateKey(EVP_PKEY *key, uint8_t *& encodedKey, uint32_t& encodedKeyLen);
extern bool WeaveEncodeECPrivateKey(EC_KEY *key, bool includePubKey, uint8_t *& encodedKey, uint32_t& encodedKeyLen);
+extern bool ReadPublicKey(const char *fileName, const char *prompt, EVP_PKEY *& key);
+extern bool DecodePublicKey(const uint8_t *keyData, uint32_t keyDataLen, KeyFormat keyFormat, const char *keySource, const char *prompt, EVP_PKEY *& key);
+extern KeyFormat DetectPublicKeyFormat(const uint8_t *key, uint32_t keyLen);
extern bool InitOpenSSL();
extern OID NIDToWeaveOID(int nid);