From 97e0e07307f16cd38c418816c65cda396f78232f Mon Sep 17 00:00:00 2001 From: Evgeny Margolis Date: Fri, 9 Sep 2022 09:55:54 -0700 Subject: [PATCH] chip-cert: Updated Tool to Support Comand Line Key/Cert Inputs. (#22142) (#22436) Other text updates. Co-authored-by: Andrei Litvin --- src/tools/chip-cert/CertUtils.cpp | 84 +++++---- src/tools/chip-cert/Cmd_ConvertCert.cpp | 30 ++-- src/tools/chip-cert/Cmd_ConvertKey.cpp | 27 +-- src/tools/chip-cert/Cmd_GenAttCert.cpp | 64 +++---- src/tools/chip-cert/Cmd_GenCD.cpp | 41 ++--- src/tools/chip-cert/Cmd_GenCert.cpp | 48 ++--- src/tools/chip-cert/Cmd_PrintCert.cpp | 20 +-- src/tools/chip-cert/Cmd_ResignCert.cpp | 47 ++--- src/tools/chip-cert/Cmd_ValidateAttCert.cpp | 54 +++--- src/tools/chip-cert/Cmd_ValidateCert.cpp | 20 ++- src/tools/chip-cert/KeyUtils.cpp | 48 +++-- src/tools/chip-cert/README.md | 189 +++++++++++++------- src/tools/chip-cert/chip-cert.h | 10 +- 13 files changed, 383 insertions(+), 299 deletions(-) diff --git a/src/tools/chip-cert/CertUtils.cpp b/src/tools/chip-cert/CertUtils.cpp index f929e1446317e2..53975b7d89f020 100644 --- a/src/tools/chip-cert/CertUtils.cpp +++ b/src/tools/chip-cert/CertUtils.cpp @@ -508,51 +508,52 @@ bool AddAuthorityKeyId(X509 * cert, X509 * caCert) return res; } -bool ReadCertPEM(const char * fileName, X509 * cert) -{ - bool res = true; - FILE * file = nullptr; - - res = OpenFile(fileName, file); - VerifyTrueOrExit(res); - - if (PEM_read_X509(file, &cert, nullptr, nullptr) == nullptr) - { - ReportOpenSSLErrorAndExit("PEM_read_X509", res = false); - } - -exit: - CloseFile(file); - return res; -} - } // namespace -bool ReadCert(const char * fileName, X509 * cert) +bool ReadCert(const char * fileNameOrStr, X509 * cert) { CertFormat origCertFmt; - return ReadCert(fileName, cert, origCertFmt); + return ReadCert(fileNameOrStr, cert, origCertFmt); } -bool ReadCert(const char * fileName, X509 * cert, CertFormat & certFmt) +bool ReadCert(const char * fileNameOrStr, X509 * cert, CertFormat & certFmt) { bool res = true; uint32_t certLen = 0; std::unique_ptr certBuf; - res = ReadFileIntoMem(fileName, nullptr, certLen); - VerifyTrueOrExit(res); + // If fileNameOrStr is a file name + if (access(fileNameOrStr, R_OK) == 0) + { + res = ReadFileIntoMem(fileNameOrStr, nullptr, certLen); + VerifyTrueOrExit(res); - certBuf = std::unique_ptr(new uint8_t[certLen]); + certBuf = std::unique_ptr(new uint8_t[certLen]); - res = ReadFileIntoMem(fileName, certBuf.get(), certLen); - VerifyTrueOrExit(res); + res = ReadFileIntoMem(fileNameOrStr, certBuf.get(), certLen); + VerifyTrueOrExit(res); - certFmt = DetectCertFormat(certBuf.get(), certLen); - if (certFmt == kCertFormat_Unknown) + certFmt = DetectCertFormat(certBuf.get(), certLen); + if (certFmt == kCertFormat_Unknown) + { + fprintf(stderr, "Unrecognized Cert Format in File: %s\n", fileNameOrStr); + return false; + } + } + // Otherwise, treat fileNameOrStr as a pointer to the certificate string + else { - fprintf(stderr, "Unrecognized Cert Format in File: %s\n", fileName); - return false; + certLen = static_cast(strlen(fileNameOrStr)); + + certFmt = DetectCertFormat(reinterpret_cast(fileNameOrStr), certLen); + if (certFmt == kCertFormat_Unknown) + { + fprintf(stderr, "Unrecognized Cert Format in the Input Argument: %s\n", fileNameOrStr); + return false; + } + + certBuf = std::unique_ptr(new uint8_t[certLen]); + memcpy(certBuf.get(), fileNameOrStr, certLen); } if ((certFmt == kCertFormat_X509_Hex) || (certFmt == kCertFormat_Chip_Hex)) @@ -565,8 +566,15 @@ bool ReadCert(const char * fileName, X509 * cert, CertFormat & certFmt) if (certFmt == kCertFormat_X509_PEM) { - res = ReadCertPEM(fileName, cert); - VerifyTrueOrExit(res); + VerifyOrReturnError(chip::CanCastTo(certLen), false); + + std::unique_ptr certBIO( + BIO_new_mem_buf(static_cast(certBuf.get()), static_cast(certLen)), &BIO_free_all); + + if (PEM_read_bio_X509(certBIO.get(), &cert, nullptr, nullptr) == nullptr) + { + ReportOpenSSLErrorAndExit("PEM_read_bio_X509", res = false); + } } else if ((certFmt == kCertFormat_X509_DER) || (certFmt == kCertFormat_X509_Hex)) { @@ -612,12 +620,12 @@ bool ReadCert(const char * fileName, X509 * cert, CertFormat & certFmt) return res; } -bool ReadCertDERRaw(const char * fileName, MutableByteSpan & cert) +bool ReadCertDER(const char * fileNameOrStr, MutableByteSpan & cert) { bool res = true; std::unique_ptr certX509(X509_new(), &X509_free); - VerifyOrReturnError(ReadCertPEM(fileName, certX509.get()) == true, false); + VerifyOrReturnError(ReadCert(fileNameOrStr, certX509.get()), false); uint8_t * certPtr = cert.data(); int certLen = i2d_X509(certX509.get(), &certPtr); @@ -660,14 +668,14 @@ bool X509ToChipCert(X509 * cert, MutableByteSpan & chipCert) return res; } -bool LoadChipCert(const char * fileName, bool isTrused, ChipCertificateSet & certSet, MutableByteSpan & chipCert) +bool LoadChipCert(const char * fileNameOrStr, bool isTrused, ChipCertificateSet & certSet, MutableByteSpan & chipCert) { bool res = true; CHIP_ERROR err; BitFlags decodeFlags; std::unique_ptr cert(X509_new(), &X509_free); - res = ReadCert(fileName, cert.get()); + res = ReadCert(fileNameOrStr, cert.get()); VerifyTrueOrExit(res); res = X509ToChipCert(cert.get(), chipCert); @@ -685,7 +693,7 @@ bool LoadChipCert(const char * fileName, bool isTrused, ChipCertificateSet & cer err = certSet.LoadCert(chipCert, decodeFlags); if (err != CHIP_NO_ERROR) { - fprintf(stderr, "Error reading %s\n%s\n", fileName, chip::ErrorStr(err)); + fprintf(stderr, "Error reading %s\n%s\n", fileNameOrStr, chip::ErrorStr(err)); ExitNow(res = false); } @@ -747,8 +755,6 @@ bool WriteCert(const char * fileName, X509 * cert, CertFormat certFmt) ExitNow(res = false); } - printf("\r\n"); - exit: OPENSSL_free(derCert); CloseFile(file); diff --git a/src/tools/chip-cert/Cmd_ConvertCert.cpp b/src/tools/chip-cert/Cmd_ConvertCert.cpp index a1379388f02d0c..7eba1cc2f8868c 100644 --- a/src/tools/chip-cert/Cmd_ConvertCert.cpp +++ b/src/tools/chip-cert/Cmd_ConvertCert.cpp @@ -87,21 +87,21 @@ OptionSet gCmdOptions = HelpOptions gHelpOptions( CMD_NAME, - "Usage: " CMD_NAME " [ ] \n", + "Usage: " CMD_NAME " [ ] \n", CHIP_VERSION_STRING "\n" COPYRIGHT_STRING, - "Convert a certificate between CHIP and X509 forms.\n" + "Convert operational certificate between CHIP and X.509 formats.\n" "\n" "ARGUMENTS\n" "\n" - " \n" + " \n" "\n" - " The input certificate file name, or - to read from stdin. The\n" - " format of the input certificate is auto-detected and can be any\n" - " of: X.509 PEM, X.509 DER, CHIP base-64 or CHIP raw TLV.\n" + " File or string containing certificate to be converted.\n" + " The format of the input certificate is auto-detected and can be any of:\n" + " X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX.\n" "\n" - " \n" + " \n" "\n" - " The output certificate file name, or - to write to stdout.\n" + " The output certificate file name, or '-' to write to stdout.\n" "\n" ); @@ -113,9 +113,9 @@ OptionSet * gCmdOptionSets[] = }; // clang-format on -const char * gInFileName = nullptr; -const char * gOutFileName = nullptr; -CertFormat gOutCertFormat = kCertFormat_Default; +const char * gInFileNameOrStr = nullptr; +const char * gOutFileName = nullptr; +CertFormat gOutCertFormat = kCertFormat_Default; bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) { @@ -151,7 +151,7 @@ bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]) { if (argc == 0) { - PrintArgError("%s: Please specify the name of the input certificate file, or - for stdin.\n", progName); + PrintArgError("%s: Please specify the name of the input certificate file or the certificate string.\n", progName); return false; } @@ -167,8 +167,8 @@ bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]) return false; } - gInFileName = argv[0]; - gOutFileName = argv[1]; + gInFileNameOrStr = argv[0]; + gOutFileName = argv[1]; return true; } @@ -192,7 +192,7 @@ bool Cmd_ConvertCert(int argc, char * argv[]) res = InitOpenSSL(); VerifyTrueOrExit(res); - res = ReadCert(gInFileName, cert.get()); + res = ReadCert(gInFileNameOrStr, cert.get()); VerifyTrueOrExit(res); res = WriteCert(gOutFileName, cert.get(), gOutCertFormat); diff --git a/src/tools/chip-cert/Cmd_ConvertKey.cpp b/src/tools/chip-cert/Cmd_ConvertKey.cpp index 8f08c41d19ab9d..0df462b45663e3 100644 --- a/src/tools/chip-cert/Cmd_ConvertKey.cpp +++ b/src/tools/chip-cert/Cmd_ConvertKey.cpp @@ -110,21 +110,26 @@ OptionSet gCmdOptions = HelpOptions gHelpOptions( CMD_NAME, - "Usage: " CMD_NAME " [ ] \n", + "Usage: " CMD_NAME " [ ] \n", CHIP_VERSION_STRING "\n" COPYRIGHT_STRING, - "Convert a private key between CHIP and PEM/DER forms." + "Convert private/public key between CHIP and X.509 formats.\n" "\n" "ARGUMENTS\n" "\n" - " \n" + " \n" "\n" - " The input private key file name, or - to read from stdin. The\n" - " format of the input key is auto-detected and can be any\n" - " of: PEM, DER, CHIP base-64 or CHIP raw.\n" + " File or string containing private/public key to be converted.\n" + " The format of the input key is auto-detected and can be any of:\n" + " X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX.\n" "\n" - " \n" + " Note: the private key formats include both private and public keys, while\n" + " the public key formats include only public keys. Therefore, conversion from any\n" + " private key format to public key is supported but conversion from public key\n" + " to private CANNOT be done.\n" "\n" - " The output private key file name, or - to write to stdout.\n" + " \n" + "\n" + " The output private key file name, or '-' to write to stdout.\n" "\n" ); @@ -136,7 +141,7 @@ OptionSet *gCmdOptionSets[] = }; // clang-ormat on -const char * gInFileName = nullptr; +const char * gInFileNameOrStr = nullptr; const char * gOutFileName = nullptr; KeyFormat gOutFormat = kKeyFormat_Chip_Base64; @@ -203,7 +208,7 @@ bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]) return false; } - gInFileName = argv[0]; + gInFileNameOrStr = argv[0]; gOutFileName = argv[1]; return true; @@ -228,7 +233,7 @@ bool Cmd_ConvertKey(int argc, char * argv[]) res = InitOpenSSL(); VerifyTrueOrExit(res); - res = ReadKey(gInFileName, key); + res = ReadKey(gInFileNameOrStr, key); VerifyTrueOrExit(res); if (IsPrivateKeyFormat(gOutFormat) && EC_KEY_get0_private_key(EVP_PKEY_get1_EC_KEY(key.get())) == nullptr) diff --git a/src/tools/chip-cert/Cmd_GenAttCert.cpp b/src/tools/chip-cert/Cmd_GenAttCert.cpp index 5425e5de6a6e7a..845344860c49cd 100644 --- a/src/tools/chip-cert/Cmd_GenAttCert.cpp +++ b/src/tools/chip-cert/Cmd_GenAttCert.cpp @@ -90,27 +90,29 @@ const char * const gCmdOptionHelp = " If not specified then by default the VID and PID fields are encoded using\n" " Matter specific OIDs.\n" "\n" - " -C, --ca-cert \n" + " -C, --ca-cert \n" "\n" - " File containing CA certificate to be used to sign the new certificate.\n" + " File or string containing CA certificate to be used to sign the new certificate.\n" "\n" - " -K, --ca-key \n" + " -K, --ca-key \n" "\n" - " File containing CA private key to be used to sign the new certificate.\n" + " File or string containing CA private key to be used to sign the new certificate.\n" "\n" - " -k, --key \n" + " -k, --key \n" "\n" - " File containing the public and private keys for the new certificate (in an X.509 PEM format).\n" + " File or string containing the public and private keys for the new certificate (in an X.509 PEM format).\n" " If not specified, a new key pair will be generated.\n" "\n" - " -o, --out \n" + " -o, --out \n" "\n" " File to contain the new certificate (in an X.509 PEM format).\n" + " If specified '-' then output is written to stdout.\n" "\n" - " -O, --out-key \n" + " -O, --out-key \n" "\n" " File to contain the public/private key for the new certificate (in an X.509 PEM format).\n" " This option must be specified if the --key option is not.\n" + " If specified '-' then output is written to stdout.\n" "\n" " -f, --valid-from --
[ :: ]\n" "\n" @@ -188,7 +190,7 @@ HelpOptions gHelpOptions( CMD_NAME, "Usage: " CMD_NAME " [ ]\n", CHIP_VERSION_STRING "\n" COPYRIGHT_STRING, - "Generate a CHIP certificate" + "Generate a CHIP Attestation certificate" ); OptionSet *gCmdOptionSets[] = @@ -199,17 +201,17 @@ OptionSet *gCmdOptionSets[] = }; // clang-format on -AttCertType gAttCertType = kAttCertType_NotSpecified; -const char * gSubjectCN = nullptr; -uint16_t gSubjectVID = VendorId::NotSpecified; -uint16_t gSubjectPID = 0; -bool gEncodeVIDandPIDasCN = false; -const char * gCACertFileName = nullptr; -const char * gCAKeyFileName = nullptr; -const char * gInKeyFileName = nullptr; -const char * gOutCertFileName = nullptr; -const char * gOutKeyFileName = nullptr; -uint32_t gValidDays = kCertValidDays_Undefined; +AttCertType gAttCertType = kAttCertType_NotSpecified; +const char * gSubjectCN = nullptr; +uint16_t gSubjectVID = VendorId::NotSpecified; +uint16_t gSubjectPID = 0; +bool gEncodeVIDandPIDasCN = false; +const char * gCACertFileNameOrStr = nullptr; +const char * gCAKeyFileNameOrStr = nullptr; +const char * gInKeyFileNameOrStr = nullptr; +const char * gOutCertFileName = nullptr; +const char * gOutKeyFileName = nullptr; +uint32_t gValidDays = kCertValidDays_Undefined; struct tm gValidFrom; CertStructConfig gCertConfig; @@ -261,13 +263,13 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char gEncodeVIDandPIDasCN = true; break; case 'k': - gInKeyFileName = arg; + gInKeyFileNameOrStr = arg; break; case 'C': - gCACertFileName = arg; + gCACertFileNameOrStr = arg; break; case 'K': - gCAKeyFileName = arg; + gCAKeyFileNameOrStr = arg; break; case 'o': gOutCertFileName = arg; @@ -474,19 +476,19 @@ bool Cmd_GenAttCert(int argc, char * argv[]) } } - if (gCACertFileName == nullptr && gAttCertType != kAttCertType_PAA) + if (gCACertFileNameOrStr == nullptr && gAttCertType != kAttCertType_PAA) { fprintf(stderr, "Please specify the CA certificate file name using the --ca-cert option.\n"); return false; } - if (gCACertFileName != nullptr && gAttCertType == kAttCertType_PAA) + if (gCACertFileNameOrStr != nullptr && gAttCertType == kAttCertType_PAA) { fprintf(stderr, "Please don't specify --ca-cert option for the self signed certificate. \n"); return false; } - if (gCACertFileName != nullptr && gCAKeyFileName == nullptr) + if (gCACertFileNameOrStr != nullptr && gCAKeyFileNameOrStr == nullptr) { fprintf(stderr, "Please specify the CA key file name using the --ca-key option.\n"); return false; @@ -498,7 +500,7 @@ bool Cmd_GenAttCert(int argc, char * argv[]) return false; } - if (gInKeyFileName == nullptr && gOutKeyFileName == nullptr) + if (gInKeyFileNameOrStr == nullptr && gOutKeyFileName == nullptr) { fprintf(stderr, "Please specify the file name for the new public/private key using the --out-key option.\n"); return false; @@ -531,9 +533,9 @@ bool Cmd_GenAttCert(int argc, char * argv[]) res = InitOpenSSL(); VerifyTrueOrExit(res); - if (gInKeyFileName != nullptr) + if (gInKeyFileNameOrStr != nullptr) { - res = ReadKey(gInKeyFileName, newKey); + res = ReadKey(gInKeyFileNameOrStr, newKey); VerifyTrueOrExit(res); } else @@ -561,10 +563,10 @@ bool Cmd_GenAttCert(int argc, char * argv[]) std::unique_ptr caCert(X509_new(), &X509_free); std::unique_ptr caKey(EVP_PKEY_new(), &EVP_PKEY_free); - res = ReadCert(gCACertFileName, caCert.get()); + res = ReadCert(gCACertFileNameOrStr, caCert.get()); VerifyTrueOrExit(res); - res = ReadKey(gCAKeyFileName, caKey, gCertConfig.IsErrorTestCaseEnabled()); + res = ReadKey(gCAKeyFileNameOrStr, caKey, gCertConfig.IsErrorTestCaseEnabled()); VerifyTrueOrExit(res); res = MakeAttCert(gAttCertType, gSubjectCN, gSubjectVID, gSubjectPID, gEncodeVIDandPIDasCN, caCert.get(), caKey.get(), diff --git a/src/tools/chip-cert/Cmd_GenCD.cpp b/src/tools/chip-cert/Cmd_GenCD.cpp index 07d2ac2b510c83..36f15f1a5a8324 100644 --- a/src/tools/chip-cert/Cmd_GenCD.cpp +++ b/src/tools/chip-cert/Cmd_GenCD.cpp @@ -72,19 +72,20 @@ OptionDef gCmdOptionDefs[] = }; const char * const gCmdOptionHelp = - " -K, --key \n" + " -K, --key \n" "\n" - " File containing private key to be used to sign the Certification Declaration.\n" + " File or string containing private key to be used to sign the Certification Declaration.\n" "\n" - " -C, --cert \n" + " -C, --cert \n" "\n" - " File containing certificate associated with the private key that is used\n" + " File or string containing certificate associated with the private key that is used\n" " to sign the Certification Declaration. The Subject Key Identifier in the\n" " certificate will be included in the signed Certification Declaration message.\n" "\n" - " -O, --out \n" + " -O, --out \n" "\n" " File to contain the signed Certification Declaration message.\n" + " If specified '-' then output is written to stdout.\n" "\n" " -f, --format-version \n" "\n" @@ -134,9 +135,9 @@ const char * const gCmdOptionHelp = "\n" " DAC Origin Product Id in hex.\n" "\n" - " -a, --authorized-paa-cert \n" + " -a, --authorized-paa-cert \n" "\n" - " File containing PAA certificate authorized to sign PAI which signs the DAC\n" + " File or string containing PAA certificate authorized to sign PAI which signs the DAC\n" " for a product carrying this CD. This field is optional and if present, only specified\n" " PAAs will be authorized to sign device's PAI for the lifetime of the generated CD.\n" " Maximum 10 authorized PAA certificates can be specified.\n" @@ -360,9 +361,9 @@ class CDStructConfig }; CertificationElements gCertElements; -const char * gCertFileName = nullptr; -const char * gKeyFileName = nullptr; -const char * gSignedCDFileName = nullptr; +const char * gCertFileNameOrStr = nullptr; +const char * gKeyFileNameOrStr = nullptr; +const char * gSignedCDFileName = nullptr; CDStructConfig gCDConfig; bool ExtractSKIDFromX509Cert(X509 * cert, ByteSpan & skid) @@ -380,10 +381,10 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char switch (id) { case 'C': - gCertFileName = arg; + gCertFileNameOrStr = arg; break; case 'K': - gKeyFileName = arg; + gKeyFileNameOrStr = arg; break; case 'O': gSignedCDFileName = arg; @@ -483,9 +484,9 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char return false; } { - const char * fileName = arg; + const char * fileNameOrStr = arg; std::unique_ptr cert(X509_new(), &X509_free); - VerifyOrReturnError(ReadCert(fileName, cert.get()), false); + VerifyOrReturnError(ReadCert(fileNameOrStr, cert.get()), false); ByteSpan skid; VerifyOrReturnError(ExtractSKIDFromX509Cert(cert.get(), skid), false); @@ -1098,15 +1099,15 @@ bool Cmd_GenCD(int argc, char * argv[]) "declaration.\n"); } - if (gKeyFileName == nullptr) + if (gKeyFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the signing private key file name using the --key option.\n"); + fprintf(stderr, "Please specify the signing private key using the --key option.\n"); return false; } - if (gCertFileName == nullptr) + if (gCertFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the signing certificate file name using the --cert option.\n"); + fprintf(stderr, "Please specify the signing certificate using the --cert option.\n"); return false; } @@ -1146,8 +1147,8 @@ bool Cmd_GenCD(int argc, char * argv[]) std::unique_ptr cert(X509_new(), &X509_free); std::unique_ptr key(EVP_PKEY_new(), &EVP_PKEY_free); - VerifyOrReturnError(ReadCert(gCertFileName, cert.get()), false); - VerifyOrReturnError(ReadKey(gKeyFileName, key), false); + VerifyOrReturnError(ReadCert(gCertFileNameOrStr, cert.get()), false); + VerifyOrReturnError(ReadKey(gKeyFileNameOrStr, key), false); // Extract the subject key id from the X509 certificate. ByteSpan signerKeyId; diff --git a/src/tools/chip-cert/Cmd_GenCert.cpp b/src/tools/chip-cert/Cmd_GenCert.cpp index e944bdb07733c9..e53a063b4ca050 100644 --- a/src/tools/chip-cert/Cmd_GenCert.cpp +++ b/src/tools/chip-cert/Cmd_GenCert.cpp @@ -110,27 +110,29 @@ const char * const gCmdOptionHelp = "\n" " NID_info_access extension to be added to the list of certificate extensions.\n" "\n" - " -C, --ca-cert \n" + " -C, --ca-cert \n" "\n" - " File containing CA certificate to be used to sign the new certificate.\n" + " File or string containing CA certificate to be used to sign the new certificate.\n" "\n" - " -K, --ca-key \n" + " -K, --ca-key \n" "\n" - " File containing CA private key to be used to sign the new certificate.\n" + " File or string containing CA private key to be used to sign the new certificate.\n" "\n" - " -k, --key \n" + " -k, --key \n" "\n" - " File containing the public and private keys for the new certificate.\n" + " File or string containing the public and private keys for the new certificate.\n" " If not specified, a new key pair will be generated.\n" "\n" - " -o, --out \n" + " -o, --out \n" "\n" " File to contain the new certificate.\n" + " If specified '-' then output is written to stdout.\n" "\n" - " -O, --out-key \n" + " -O, --out-key \n" "\n" " File to contain the public/private key for the new certificate.\n" " This option must be specified if the --key option is not.\n" + " If specified '-' then output is written to stdout.\n" "\n" " -F, --out-format \n" "\n" @@ -246,9 +248,9 @@ ToolChipDN gSubjectDN; uint8_t gCertType = kCertType_NotSpecified; int gPathLengthConstraint = kPathLength_NotSpecified; bool gSelfSign = false; -const char * gCACertFileName = nullptr; -const char * gCAKeyFileName = nullptr; -const char * gInKeyFileName = nullptr; +const char * gCACertFileNameOrStr = nullptr; +const char * gCAKeyFileNameOrStr = nullptr; +const char * gInKeyFileNameOrStr = nullptr; const char * gOutCertFileName = nullptr; const char * gOutKeyFileName = nullptr; CertFormat gOutCertFormat = kCertFormat_Default; @@ -426,13 +428,13 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char gFutureExtensionsCount++; break; case 'k': - gInKeyFileName = arg; + gInKeyFileNameOrStr = arg; break; case 'C': - gCACertFileName = arg; + gCACertFileNameOrStr = arg; break; case 'K': - gCAKeyFileName = arg; + gCAKeyFileNameOrStr = arg; break; case 'o': gOutCertFileName = arg; @@ -747,18 +749,18 @@ bool Cmd_GenCert(int argc, char * argv[]) } } - if (gCACertFileName == nullptr && !gSelfSign) + if (gCACertFileNameOrStr == nullptr && !gSelfSign) { - fprintf(stderr, "Please specify the CA certificate file name using the --ca-cert option.\n"); + fprintf(stderr, "Please specify the CA certificate using the --ca-cert option.\n"); ExitNow(res = false); } - else if (gCACertFileName != nullptr && gSelfSign) + else if (gCACertFileNameOrStr != nullptr && gSelfSign) { fprintf(stderr, "Please don't specify --ca-cert option for the self signed certificate. \n"); ExitNow(res = false); } - if (gCACertFileName != nullptr && gCAKeyFileName == nullptr) + if (gCACertFileNameOrStr != nullptr && gCAKeyFileNameOrStr == nullptr) { fprintf(stderr, "Please specify the CA key file name using the --ca-key option.\n"); ExitNow(res = false); @@ -770,7 +772,7 @@ bool Cmd_GenCert(int argc, char * argv[]) ExitNow(res = false); } - if (gInKeyFileName == nullptr && gOutKeyFileName == nullptr) + if (gInKeyFileNameOrStr == nullptr && gOutKeyFileName == nullptr) { fprintf(stderr, "Please specify the file name for the new public/private key using the --out-key option.\n"); ExitNow(res = false); @@ -810,9 +812,9 @@ bool Cmd_GenCert(int argc, char * argv[]) res = InitOpenSSL(); VerifyTrueOrExit(res); - if (gInKeyFileName != nullptr) + if (gInKeyFileNameOrStr != nullptr) { - res = ReadKey(gInKeyFileName, newKey); + res = ReadKey(gInKeyFileNameOrStr, newKey); VerifyTrueOrExit(res); } else @@ -836,10 +838,10 @@ bool Cmd_GenCert(int argc, char * argv[]) } else { - res = ReadCert(gCACertFileName, caCert.get()); + res = ReadCert(gCACertFileNameOrStr, caCert.get()); VerifyTrueOrExit(res); - res = ReadKey(gCAKeyFileName, caKey); + res = ReadKey(gCAKeyFileNameOrStr, caKey); VerifyTrueOrExit(res); caCertPtr = caCert.get(); diff --git a/src/tools/chip-cert/Cmd_PrintCert.cpp b/src/tools/chip-cert/Cmd_PrintCert.cpp index 2bef2ed868c2a2..5ccc9fb536b446 100644 --- a/src/tools/chip-cert/Cmd_PrintCert.cpp +++ b/src/tools/chip-cert/Cmd_PrintCert.cpp @@ -46,10 +46,10 @@ OptionDef gCmdOptionDefs[] = }; const char * const gCmdOptionHelp = - " -o, --out\n" + " -o, --out \n" "\n" " The output printed certificate file name. If not specified\n" - " or if specified - then output is written to stdout.\n" + " or if specified '-' then output is written to stdout.\n" "\n" ; @@ -63,15 +63,15 @@ OptionSet gCmdOptions = HelpOptions gHelpOptions( CMD_NAME, - "Usage: " CMD_NAME " [] \n", + "Usage: " CMD_NAME " [] \n", CHIP_VERSION_STRING "\n" COPYRIGHT_STRING, - "Print a CHIP certificate.\n" + "Print a CHIP operational certificate.\n" "\n" "ARGUMENTS\n" "\n" - " \n" + " \n" "\n" - " A file containing a CHIP certificate.\n" + " File or string containing a CHIP certificate.\n" "\n" ); @@ -83,8 +83,8 @@ OptionSet *gCmdOptionSets[] = }; // clang-format on -const char * gInFileName = nullptr; -const char * gOutFileName = "-"; +const char * gInFileNameOrStr = nullptr; +const char * gOutFileName = "-"; bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) { @@ -115,7 +115,7 @@ bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]) return false; } - gInFileName = argv[0]; + gInFileNameOrStr = argv[0]; return true; } @@ -385,7 +385,7 @@ bool Cmd_PrintCert(int argc, char * argv[]) res = ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets, HandleNonOptionArgs); VerifyTrueOrExit(res); - res = ReadCert(gInFileName, cert.get()); + res = ReadCert(gInFileNameOrStr, cert.get()); VerifyTrueOrExit(res); res = PrintCert(gOutFileName, cert.get()); diff --git a/src/tools/chip-cert/Cmd_ResignCert.cpp b/src/tools/chip-cert/Cmd_ResignCert.cpp index 53d33ad480f23b..053b5ff917d0b9 100644 --- a/src/tools/chip-cert/Cmd_ResignCert.cpp +++ b/src/tools/chip-cert/Cmd_ResignCert.cpp @@ -52,21 +52,22 @@ OptionDef gCmdOptionDefs[] = }; const char * const gCmdOptionHelp = - " -c, --cert \n" + " -c, --cert \n" "\n" - " File containing the certificate to be re-signed.\n" + " File or string containing the certificate to be re-signed.\n" "\n" - " -o, --out \n" + " -o, --out \n" "\n" " File to contain the re-signed certificate.\n" + " If specified '-' then output is written to stdout.\n" "\n" - " -C, --ca-cert \n" + " -C, --ca-cert \n" "\n" - " File containing CA certificate to be used to re-sign the certificate.\n" + " File or string containing CA certificate to be used to re-sign the certificate.\n" "\n" - " -K, --ca-key \n" + " -K, --ca-key \n" "\n" - " File containing CA private key to be used to re-sign the certificate.\n" + " File or string containing CA private key to be used to re-sign the certificate.\n" "\n" " -s, --self\n" "\n" @@ -97,27 +98,27 @@ OptionSet * gCmdOptionSets[] = }; // clang-format on -const char * gInCertFileName = nullptr; -const char * gOutCertFileName = nullptr; -const char * gCACertFileName = nullptr; -const char * gCAKeyFileName = nullptr; -bool gSelfSign = false; +const char * gInCertFileNameOrStr = nullptr; +const char * gOutCertFileName = nullptr; +const char * gCACertFileNameOrStr = nullptr; +const char * gCAKeyFileNameOrStr = nullptr; +bool gSelfSign = false; bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) { switch (id) { case 'c': - gInCertFileName = arg; + gInCertFileNameOrStr = arg; break; case 'o': gOutCertFileName = arg; break; case 'C': - gCACertFileName = arg; + gCACertFileNameOrStr = arg; break; case 'K': - gCAKeyFileName = arg; + gCAKeyFileNameOrStr = arg; break; case 's': gSelfSign = true; @@ -148,7 +149,7 @@ bool Cmd_ResignCert(int argc, char * argv[]) res = ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets); VerifyTrueOrExit(res); - if (gInCertFileName == nullptr) + if (gInCertFileNameOrStr == nullptr) { fprintf(stderr, "Please specify certificate to be resigned using --cert option.\n"); ExitNow(res = false); @@ -160,22 +161,22 @@ bool Cmd_ResignCert(int argc, char * argv[]) ExitNow(res = false); } - if (gCACertFileName == nullptr && !gSelfSign) + if (gCACertFileNameOrStr == nullptr && !gSelfSign) { fprintf(stderr, "Please specify a CA certificate to be used to sign the new certificate (using\n" "the --ca-cert option) or --self to generate a self-signed certificate.\n"); ExitNow(res = false); } - else if (gCACertFileName != nullptr && gSelfSign) + else if (gCACertFileNameOrStr != nullptr && gSelfSign) { fprintf(stderr, "Please specify only one of --ca-cert and --self.\n"); ExitNow(res = false); } - if (gCAKeyFileName == nullptr) + if (gCAKeyFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the CA key file name using the --ca-key option.\n"); + fprintf(stderr, "Please specify the CA key using the --ca-key option.\n"); ExitNow(res = false); } @@ -191,17 +192,17 @@ bool Cmd_ResignCert(int argc, char * argv[]) res = InitOpenSSL(); VerifyTrueOrExit(res); - res = ReadCert(gInCertFileName, cert.get(), inCertFmt); + res = ReadCert(gInCertFileNameOrStr, cert.get(), inCertFmt); VerifyTrueOrExit(res); - res = ReadKey(gCAKeyFileName, caKey); + res = ReadKey(gCAKeyFileNameOrStr, caKey); VerifyTrueOrExit(res); if (!gSelfSign) { std::unique_ptr caCert(X509_new(), &X509_free); - res = ReadCert(gCACertFileName, caCert.get()); + res = ReadCert(gCACertFileNameOrStr, caCert.get()); VerifyTrueOrExit(res); res = ResignCert(cert.get(), caCert.get(), caKey.get()); diff --git a/src/tools/chip-cert/Cmd_ValidateAttCert.cpp b/src/tools/chip-cert/Cmd_ValidateAttCert.cpp index 0d048b6898604c..15d33ca7bd2a5c 100644 --- a/src/tools/chip-cert/Cmd_ValidateAttCert.cpp +++ b/src/tools/chip-cert/Cmd_ValidateAttCert.cpp @@ -49,20 +49,20 @@ OptionDef gCmdOptionDefs[] = }; const char * const gCmdOptionHelp = - " -d, --dac \n" + " -d, --dac \n" "\n" - " A file containing Device Attestation Certificate (DAC) to be\n" - " validated. The DAC is provided in the DER encoded format.\n" + " File or string containing Device Attestation Certificate (DAC) to be validated.\n" + " The DAC format is auto-detected and can be any of: X.509 PEM, DER or HEX formats.\n" "\n" - " -i, --pai \n" + " -i, --pai \n" "\n" - " A file containing Product Attestation Intermediate (PAI) Certificate.\n" - " The PAI is provided in the DER encoded format.\n" + " File or string containing Product Attestation Intermediate (PAI) Certificate.\n" + " The PAI format is auto-detected and can be any of: X.509 PEM, DER or HEX formats.\n" "\n" - " -a, --paa \n" + " -a, --paa \n" "\n" - " A file containing trusted Product Attestation Authority (PAA) Certificate.\n" - " The PAA is provided in the DER encoded format.\n" + " File or string containing trusted Product Attestation Authority (PAA) Certificate.\n" + " The PAA format is auto-detected and can be any of: X.509 PEM, DER or HEX formats.\n" "\n" ; @@ -89,22 +89,22 @@ OptionSet * gCmdOptionSets[] = }; // clang-format on -const char * gDACFileName = nullptr; -const char * gPAIFileName = nullptr; -const char * gPAAFileName = nullptr; +const char * gDACFileNameOrStr = nullptr; +const char * gPAIFileNameOrStr = nullptr; +const char * gPAAFileNameOrStr = nullptr; bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) { switch (id) { case 'd': - gDACFileName = arg; + gDACFileNameOrStr = arg; break; case 'i': - gPAIFileName = arg; + gPAIFileNameOrStr = arg; break; case 'a': - gPAAFileName = arg; + gPAAFileNameOrStr = arg; break; default: PrintArgError("%s: Unhandled option: %s\n", progName, name); @@ -171,37 +171,37 @@ bool Cmd_ValidateAttCert(int argc, char * argv[]) VerifyOrReturnError(ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets), false); - if (gDACFileName == nullptr) + if (gDACFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the DAC certificate file name using the --dac option.\n"); + fprintf(stderr, "Please specify the DAC certificate using the --dac option.\n"); return false; } - if (gPAIFileName == nullptr) + if (gPAIFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the PAI certificate file name using the --pai option.\n"); + fprintf(stderr, "Please specify the PAI certificate using the --pai option.\n"); return false; } - if (gPAAFileName == nullptr) + if (gPAAFileNameOrStr == nullptr) { - fprintf(stderr, "Please specify the PAA certificate file name using the --paa option.\n"); + fprintf(stderr, "Please specify the PAA certificate using the --paa option.\n"); return false; } - if (!ReadCertDERRaw(gDACFileName, dac)) + if (!ReadCertDER(gDACFileNameOrStr, dac)) { - fprintf(stderr, "Unable to open DAC Certificate File: %s\n", gDACFileName); + fprintf(stderr, "Failed to read DAC Certificate: %s\n", gDACFileNameOrStr); return false; } - if (!ReadCertDERRaw(gPAIFileName, pai)) + if (!ReadCertDER(gPAIFileNameOrStr, pai)) { - fprintf(stderr, "Unable to open PAI Certificate File: %s\n", gPAIFileName); + fprintf(stderr, "Failed to read PAI Certificate: %s\n", gPAIFileNameOrStr); return false; } - if (!ReadCertDERRaw(gPAAFileName, paa)) + if (!ReadCertDER(gPAAFileNameOrStr, paa)) { - fprintf(stderr, "Unable to open PAA Certificate File: %s\n", gPAAFileName); + fprintf(stderr, "Failed to read PAA Certificate: %s\n", gPAAFileNameOrStr); return false; } diff --git a/src/tools/chip-cert/Cmd_ValidateCert.cpp b/src/tools/chip-cert/Cmd_ValidateCert.cpp index 6445207e8065da..c8d3b8c7305b31 100644 --- a/src/tools/chip-cert/Cmd_ValidateCert.cpp +++ b/src/tools/chip-cert/Cmd_ValidateCert.cpp @@ -50,15 +50,15 @@ OptionDef gCmdOptionDefs[] = }; const char * const gCmdOptionHelp = - " -c, --cert \n" + " -c, --cert \n" "\n" - " A file containing an untrusted CHIP certificate to be used during\n" - " validation. Usually, it is Intermediate CA certificate.\n" + " File or string containing an untrusted CHIP certificate to be used during\n" + " validation. Usually, it is Intermediate CA certificate (ICAC).\n" "\n" - " -t, --trusted-cert \n" + " -t, --trusted-cert \n" "\n" - " A file containing a trusted CHIP certificate to be used during\n" - " validation. Usually, it is trust anchor root certificate.\n" + " File or string containing a trusted CHIP certificate to be used during\n" + " validation. Usually, it is trust anchor root certificate (RCAC).\n" "\n" ; @@ -72,15 +72,17 @@ OptionSet gCmdOptions = HelpOptions gHelpOptions( CMD_NAME, - "Usage: " CMD_NAME " [ ] \n", + "Usage: " CMD_NAME " [ ] \n", CHIP_VERSION_STRING "\n" COPYRIGHT_STRING, "Validate a chain of CHIP certificates.\n" "\n" "ARGUMENTS\n" "\n" - " \n" + " \n" "\n" - " A file containing the certificate to be validated.\n" + " File or string containing the certificate to be validated.\n" + " The formats of all input certificates are auto-detected and can be any of:\n" + " X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX.\n" "\n" ); diff --git a/src/tools/chip-cert/KeyUtils.cpp b/src/tools/chip-cert/KeyUtils.cpp index 07cb7503701cb4..9cc7fc484cdc80 100644 --- a/src/tools/chip-cert/KeyUtils.cpp +++ b/src/tools/chip-cert/KeyUtils.cpp @@ -183,26 +183,45 @@ bool SerializeKeyPair(EVP_PKEY * key, P256SerializedKeypair & serializedKeypair) return true; } -bool ReadKey(const char * fileName, std::unique_ptr & key, bool ignorErrorIfUnsupportedCurve) +bool ReadKey(const char * fileNameOrStr, std::unique_ptr & key, bool ignorErrorIfUnsupportedCurve) { bool res = true; uint32_t keyDataLen = 0; KeyFormat keyFormat = kKeyFormat_Unknown; std::unique_ptr keyData; - res = ReadFileIntoMem(fileName, nullptr, keyDataLen); - VerifyTrueOrExit(res); + // If fileNameOrStr is a file name + if (access(fileNameOrStr, R_OK) == 0) + { + res = ReadFileIntoMem(fileNameOrStr, nullptr, keyDataLen); + VerifyTrueOrExit(res); - keyData = std::unique_ptr(new uint8_t[keyDataLen]); + keyData = std::unique_ptr(new uint8_t[keyDataLen]); - res = ReadFileIntoMem(fileName, keyData.get(), keyDataLen); - VerifyTrueOrExit(res); + res = ReadFileIntoMem(fileNameOrStr, keyData.get(), keyDataLen); + VerifyTrueOrExit(res); - keyFormat = DetectKeyFormat(keyData.get(), keyDataLen); - if (keyFormat == kKeyFormat_Unknown) + keyFormat = DetectKeyFormat(keyData.get(), keyDataLen); + if (keyFormat == kKeyFormat_Unknown) + { + fprintf(stderr, "Unrecognized Key Format in File: %s\n", fileNameOrStr); + return false; + } + } + // Otherwise, treat fileNameOrStr as a pointer to the key string + else { - fprintf(stderr, "Unrecognized Key Format in File: %s\n", fileName); - return false; + keyDataLen = static_cast(strlen(fileNameOrStr)); + + keyFormat = DetectKeyFormat(reinterpret_cast(fileNameOrStr), keyDataLen); + if (keyFormat == kKeyFormat_Unknown) + { + fprintf(stderr, "Unrecognized Key Format in Input Argument: %s\n", fileNameOrStr); + return false; + } + + keyData = std::unique_ptr(new uint8_t[keyDataLen]); + memcpy(keyData.get(), fileNameOrStr, keyDataLen); } if ((keyFormat == kKeyFormat_X509_Hex) || (keyFormat == kKeyFormat_Chip_Hex) || (keyFormat == kKeyFormat_Chip_Pubkey_Hex)) @@ -269,13 +288,6 @@ bool ReadKey(const char * fileName, std::unique_ptr(keyBIO.get()), keyDataLen, - reinterpret_cast(keyBIO.get()), keyDataLen); - VerifyOrReturnError(2 * len == keyDataLen, false); - } - if (d2i_PrivateKey_bio(keyBIO.get(), &tmpKeyPtr) == nullptr) { ReportOpenSSLErrorAndExit("d2i_PrivateKey_bio", res = false); @@ -426,8 +438,6 @@ bool WriteKey(const char * fileName, EVP_PKEY * key, KeyFormat keyFmt) ExitNow(res = false); } - printf("\r\n"); - exit: CloseFile(file); OPENSSL_free(derKey); diff --git a/src/tools/chip-cert/README.md b/src/tools/chip-cert/README.md index 6d7227b593baba..9c8ae1f8aaaf97 100644 --- a/src/tools/chip-cert/README.md +++ b/src/tools/chip-cert/README.md @@ -84,6 +84,18 @@ Note that in the last example the generated Node certificate and private key are stored in base-64 encoded CHIP native format and not in PEM format as in the previous examples. +The following example generates Node certificate, where the CA cert/key and the +Node key are provided as a command line arguments: + +``` +./chip-cert gen-cert --type n --subject-chip-id DEDEDEDE0000001E --subject-fab-id FAB000000000001D --valid-from "2020-10-15 14:23:43" --lifetime 7305 --ca-key 30770201010420C31A9FD24F91B28F3553C6DD0BC05DFB264FB19DE4A293457FF61CF08656F795A00A06082A8648CE3D030107A144034200046909160652E60035DEAFF5EE4DCED6E451BB171D39972874193CBDEA79E2C81198A8CA5151F0FC086556B8D63610E9DDB237DA1AFAC7378838897FA46A776BE5 --ca-cert FTABCEV4XDq64xZcJAIBNwMnFAEAAADKysrKGCYE7xcbJyYFbrW5TDcGJxMEAAAAysrKyicVHQAAAAAAsPoYJAcBJAgBMAlBBGkJFgZS5gA13q/17k3O1uRRuxcdOZcodBk8vep54sgRmKjKUVHw/AhlVrjWNhDp3bI32hr6xzeIOIl/pGp3a+U3CjUBKQEkAgAYJAJgMAQUTMntCbE2MN9jRhRZ0bmiX4LtcIYwBRTwPNuYHS2KwOmYp5Apx6b9P/ztyBgwC0D8Ieqk5XNVp4h3De3CAlndmNqPzT/yGQFkgjozuBz41efPVctoPODsGq6zKv/0RIO45obJNN8X1pGQrtv/9JVSGA== --key 04F1C53AFB1761A75FF07437018E5B76BC75F852904DC7C4607839A5D953140FFE253626FB737647F1043F61D91B5EC0D3B42A7A25FA209CAB7ACD1A76CA46ECD2 --out Chip-Node02-Cert.chip-b64 --out-format chip-b64 +``` + +Note that in the last example, to illustrate the fact that multiple key/cert +formats are supported, the CA private key is in the X509 Hex format, the CA +certificate is in the CHIP TLV base64 format and the Node public key is in the +CHIP TLV Hex format. + Now the 'chip-cert' tool can be used to validate generated Node certificate: ``` @@ -228,27 +240,29 @@ COMMAND OPTIONS NID_info_access extension to be added to the list of certificate extensions. - -C, --ca-cert + -C, --ca-cert - File containing CA certificate to be used to sign the new certificate. + File or string containing CA certificate to be used to sign the new certificate. - -K, --ca-key + -K, --ca-key - File containing CA private key to be used to sign the new certificate. + File or string containing CA private key to be used to sign the new certificate. - -k, --key + -k, --key - File containing the public and private keys for the new certificate. + File or string containing the public and private keys for the new certificate. If not specified, a new key pair will be generated. - -o, --out + -o, --out File to contain the new certificate. + If specified '-' then output is written to stdout. - -O, --out-key + -O, --out-key File to contain the public/private key for the new certificate. This option must be specified if the --key option is not. + If specified '-' then output is written to stdout. -F, --out-format @@ -256,10 +270,11 @@ COMMAND OPTIONS If not specified, the default base-64 encoded CHIP format is used. Supported format parametes are: x509-pem - X.509 PEM format - x509-der - X.509 DER format + x509-der - X.509 DER raw format + x509-hex - X.509 DER hex encoded format chip - raw CHIP TLV format - chip-hex - hex encoded CHIP TLV format chip-b64 - base-64 encoded CHIP TLV format (default) + chip-hex - hex encoded CHIP TLV format -V, --valid-from --
[ :: ] @@ -287,19 +302,19 @@ HELP OPTIONS $ ./out/debug/standalone/chip-cert convert-cert -h Usage: chip-cert convert-cert [ ] -Convert a certificate between CHIP and X509 forms. +Convert operational certificate between CHIP and X.509 formats. ARGUMENTS - + - The input certificate file name, or - to read from stdin. The - format of the input certificate is auto-detected and can be any - of: X.509 PEM, X.509 DER, CHIP base-64 or CHIP raw TLV. + File or string containing certificate to be converted. + The format of the input certificate is auto-detected and can be any of: + X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX. - + - The output certificate file name, or - to write to stdout. + The output certificate file name, or '-' to write to stdout. COMMAND OPTIONS @@ -311,6 +326,10 @@ COMMAND OPTIONS Output certificate in X.509 DER format. + -X, --x509-hex + + Output certificate in X.509 DER hex encoded format. + -c, --chip Output certificate in raw CHIP TLV format. @@ -339,18 +358,24 @@ HELP OPTIONS $ ./out/debug/standalone/chip-cert convert-key -h Usage: chip-cert convert-key [ ] -Convert a private key between CHIP and PEM/DER forms. +Convert private/public key between CHIP and X.509 formats. + ARGUMENTS - + - The input private key file name, or - to read from stdin. The - format of the input key is auto-detected and can be any - of: PEM, DER, CHIP base-64 or CHIP raw. + File or string containing private/public key to be converted. + The format of the input key is auto-detected and can be any of: + X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX. - + Note: the private key formats include both private and public keys, while + the public key formats include only public keys. Therefore, conversion from any + private key format to public key is supported but conversion from public key + to private CANNOT be done. - The output private key file name, or - to write to stdout. + + + The output private key file name, or '-' to write to stdout. COMMAND OPTIONS @@ -362,6 +387,14 @@ COMMAND OPTIONS Output the private key in SEC1/RFC-5915 DER format. + -x, --x509-hex + + Output the private key in SEC1/RFC-5915 DER hex encoded format. + + -P, --x509-pubkey-pem + + Output the public key in SEC1/RFC-5915 PEM format. + -c, --chip Output the private key in raw CHIP serialized format. @@ -374,6 +407,22 @@ COMMAND OPTIONS Output the private key in base-64 encoded CHIP serialized format. This is the default. + -e, --chip-hex + + Output the private key in hex encoded CHIP serialized format. + + -C, --chip-pubkey + + Output the raw public key. + + -B, --chip-pubkey-b64 + + Output the public key in base-64 encoded format. + + -E, --chip-pubkey-hex + + Output the public key in hex encoded format. + HELP OPTIONS -h, --help @@ -393,21 +442,22 @@ Resign a CHIP certificate using a new CA certificate/key. COMMAND OPTIONS - -c, --cert + -c, --cert - File containing the certificate to be re-signed. + File or string containing the certificate to be re-signed. - -o, --out + -o, --out File to contain the re-signed certificate. + If specified '-' then output is written to stdout. - -C, --ca-cert + -C, --ca-cert - File containing CA certificate to be used to re-sign the certificate. + File or string containing CA certificate to be used to re-sign the certificate. - -K, --ca-key + -K, --ca-key - File containing CA private key to be used to re-sign the certificate. + File or string containing CA private key to be used to re-sign the certificate. -s, --self @@ -432,21 +482,23 @@ Validate a chain of CHIP certificates. ARGUMENTS - + - A file containing the certificate to be validated. + File or string containing the certificate to be validated. + The formats of all input certificates are auto-detected and can be any of: + X.509 PEM, X.509 DER, X.509 HEX, CHIP base-64, CHIP raw TLV or CHIP HEX. COMMAND OPTIONS - -c, --cert + -c, --cert - A file containing an untrusted CHIP certificate to be used during - validation. Usually, it is Intermediate CA certificate. + File or string containing an untrusted CHIP certificate to be used during + validation. Usually, it is Intermediate CA certificate (ICAC). - -t, --trusted-cert + -t, --trusted-cert - A file containing a trusted CHIP certificate to be used during - validation. Usually, it is trust anchor root certificate. + File or string containing a trusted CHIP certificate to be used during + validation. Usually, it is trust anchor root certificate (RCAC). HELP OPTIONS @@ -463,20 +515,20 @@ HELP OPTIONS $ ./out/debug/standalone/chip-cert print-cert -h Usage: chip-cert print-cert [] -Print a CHIP certificate. +Print a CHIP operational certificate. ARGUMENTS - + - A file containing a CHIP certificate. + File or string containing a CHIP certificate. COMMAND OPTIONS - -o, --out + -o, --out The output printed certificate file name. If not specified - or if specified - then output is written to stdout. + or if specified '-' then output is written to stdout. HELP OPTIONS @@ -493,7 +545,7 @@ HELP OPTIONS $ ./out/debug/standalone/chip-cert gen-att-cert -h Usage: chip-cert gen-att-cert [ ] -Generate a CHIP certificate +Generate a CHIP Attestation certificate COMMAND OPTIONS @@ -522,27 +574,29 @@ COMMAND OPTIONS If not specified then by default the VID and PID fields are encoded using Matter specific OIDs. - -C, --ca-cert + -C, --ca-cert - File containing CA certificate to be used to sign the new certificate. + File or string containing CA certificate to be used to sign the new certificate. - -K, --ca-key + -K, --ca-key - File containing CA private key to be used to sign the new certificate. + File or string containing CA private key to be used to sign the new certificate. - -k, --key + -k, --key - File containing the public and private keys for the new certificate (in an X.509 PEM format). + File or string containing the public and private keys for the new certificate (in an X.509 PEM format). If not specified, a new key pair will be generated. - -o, --out + -o, --out File to contain the new certificate (in an X.509 PEM format). + If specified '-' then output is written to stdout. - -O, --out-key + -O, --out-key File to contain the public/private key for the new certificate (in an X.509 PEM format). This option must be specified if the --key option is not. + If specified '-' then output is written to stdout. -f, --valid-from --
[ :: ] @@ -574,20 +628,20 @@ Validate a chain of CHIP attestation certificates COMMAND OPTIONS - -d, --dac + -d, --dac - A file containing Device Attestation Certificate (DAC) to be - validated. The DAC is provided in the DER encoded format. + File or string containing Device Attestation Certificate (DAC) to be validated. + The DAC format is auto-detected and can be any of: X.509 PEM, DER or HEX formats. - -i, --pai + -i, --pai - A file containing Product Attestation Intermediate (PAI) Certificate. - The PAI is provided in the DER encoded format. + File or string containing Product Attestation Intermediate (PAI) Certificate. + The PAI format is auto-detected and can be any of: X.509 PEM, DER or HEX formats. - -a, --paa + -a, --paa - A file containing trusted Product Attestation Authority (PAA) Certificate. - The PAA is provided in the DER encoded format. + File or string containing trusted Product Attestation Authority (PAA) Certificate. + The PAA format is auto-detected and can be any of: X.509 PEM, DER or HEX formats. HELP OPTIONS @@ -608,19 +662,20 @@ Generate CD CMS Signed Message COMMAND OPTIONS - -K, --key + -K, --key - File containing private key to be used to sign the Certification Declaration. + File or string containing private key to be used to sign the Certification Declaration. - -C, --cert + -C, --cert - File containing certificate associated with the private key that is used + File or string containing certificate associated with the private key that is used to sign the Certification Declaration. The Subject Key Identifier in the certificate will be included in the signed Certification Declaration message. - -O, --out + -O, --out File to contain the signed Certification Declaration message. + If specified '-' then output is written to stdout. -f, --format-version diff --git a/src/tools/chip-cert/chip-cert.h b/src/tools/chip-cert/chip-cert.h index 6bdd41855c3a01..1579cb4e213ab7 100644 --- a/src/tools/chip-cert/chip-cert.h +++ b/src/tools/chip-cert/chip-cert.h @@ -400,10 +400,10 @@ extern bool Cmd_ValidateCert(int argc, char * argv[]); extern bool Cmd_PrintCert(int argc, char * argv[]); extern bool Cmd_GenAttCert(int argc, char * argv[]); -extern bool ReadCert(const char * fileName, X509 * cert); -extern bool ReadCert(const char * fileName, X509 * cert, CertFormat & origCertFmt); -extern bool ReadCertDERRaw(const char * fileName, chip::MutableByteSpan & cert); -extern bool LoadChipCert(const char * fileName, bool isTrused, chip::Credentials::ChipCertificateSet & certSet, +extern bool ReadCert(const char * fileNameOrStr, X509 * cert); +extern bool ReadCert(const char * fileNameOrStr, X509 * cert, CertFormat & origCertFmt); +extern bool ReadCertDER(const char * fileNameOrStr, chip::MutableByteSpan & cert); +extern bool LoadChipCert(const char * fileNameOrStr, bool isTrused, chip::Credentials::ChipCertificateSet & certSet, chip::MutableByteSpan & chipCert); extern bool WriteCert(const char * fileName, X509 * cert, CertFormat certFmt); @@ -423,7 +423,7 @@ extern bool MakeAttCert(AttCertType attCertType, const char * subjectCN, uint16_ X509 * newCert, EVP_PKEY * newKey, CertStructConfig & certConfig); extern bool GenerateKeyPair(EVP_PKEY * key); extern bool GenerateKeyPair_Secp256k1(EVP_PKEY * key); -extern bool ReadKey(const char * fileName, std::unique_ptr & key, +extern bool ReadKey(const char * fileNameOrStr, std::unique_ptr & key, bool ignorErrorIfUnsupportedCurve = false); extern bool WriteKey(const char * fileName, EVP_PKEY * key, KeyFormat keyFmt); extern bool SerializeKeyPair(EVP_PKEY * key, chip::Crypto::P256SerializedKeypair & serializedKeypair);