qtgrpc_chat_server: Compile certificates into the application

The previous approach was error-prone, as using TARGET_FILE_DIR
hard-coded the path to the build directory and ignored install locations
entirely.

Fix this by using a more reliable approach: embedding the certificate
strings directly into the application.

Pick-to: 6.9 6.9.0 6.8 6.8.3
Change-Id: Ifb883891fd55bb023e7f9828f9c422ea3e5d1c3e
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Dennis Oberst 2025-03-13 11:36:50 +01:00
parent 662dac4244
commit c0496671be
4 changed files with 39 additions and 64 deletions

View File

@ -77,33 +77,8 @@ add_executable(qtgrpc_chat_server
target_include_directories(qtgrpc_chat_server PRIVATE ${proto_out})
target_link_libraries(qtgrpc_chat_server PRIVATE gRPC::grpc++ gRPC::grpc++_reflection)
target_compile_definitions(qtgrpc_chat_server
PRIVATE SERVER_DIR="$<TARGET_FILE_DIR:qtgrpc_chat_server>"
)
install(TARGETS qtgrpc_chat_server
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)
# copy the required certificates
add_custom_command(
TARGET qtgrpc_chat_server PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_LIST_DIR}/credentials/localhost.crt ${CMAKE_CURRENT_BINARY_DIR}/credentials/localhost.crt
COMMENT "Copying certificates to build directory"
)
add_custom_command(
TARGET qtgrpc_chat_server PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_LIST_DIR}/credentials/localhost.key ${CMAKE_CURRENT_BINARY_DIR}/credentials/localhost.key
COMMENT "Copying certificates to build directory"
)
install(FILES
${CMAKE_CURRENT_LIST_DIR}/credentials/localhost.crt
${CMAKE_CURRENT_LIST_DIR}/credentials/localhost.key
DESTINATION "${INSTALL_EXAMPLEDIR}/credentials"
)

View File

@ -1,3 +1,11 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#pragma once
#include <string>
inline static const std::string LocalhostKey = R"(
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDESiUqTSCcFfW+
b56UX922NrvOoJdlbDPT9KVHvtaFREu+TBiAwQBrZkgpFo45sAwfzdc77R1zMk40
@ -26,3 +34,31 @@ J6W8kIdr9Y20VgKRF7BQk5ixj0GKflisMHXI4t0UnheEBHWemlTu1UyCSEvBhUZO
NymTN9W6Eoe5Af1d13lTLmlsY2DfvyCokR3u2alg9zp67ScwFEHeVQQktFd0jWCQ
c8jTsJ0LJjacI0O0aUAZFQ==
-----END PRIVATE KEY-----
)";
inline static const std::string LocalhostCert = R"(
-----BEGIN CERTIFICATE-----
MIID+jCCAuKgAwIBAgIUeE21DpxD/pqYPrbpPguKo9mpQKswDQYJKoZIhvcNAQEL
BQAwgZMxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
cmxpbjEcMBoGA1UECgwTVGhlIFF0IENvbXBhbnkgR21iSDEMMAoGA1UECwwDUiZE
MRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEWE2Rlbm5pcy5vYmVy
c3RAcXQuaW8wIBcNMjUwMjA0MDgzMjQxWhgPMjEyNTAxMTEwODMyNDFaMIGTMQsw
CQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xHDAa
BgNVBAoME1RoZSBRdCBDb21wYW55IEdtYkgxDDAKBgNVBAsMA1ImRDESMBAGA1UE
AwwJbG9jYWxob3N0MSIwIAYJKoZIhvcNAQkBFhNkZW5uaXMub2JlcnN0QHF0Lmlv
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxEolKk0gnBX1vm+elF/d
tja7zqCXZWwz0/SlR77WhURLvkwYgMEAa2ZIKRaOObAMH83XO+0dczJOND/kT6z1
TblC5+3r9K/GnRi/1tJGKHKRDaIJqXl6d+lmkEm5ToLIjTMqhctxHfuaqletoe0u
kTY8m1xDG7UaSdIQvttXA8JqT5WDAl79Y+OnXXRxnYIEzOqSICNgzW4KP3i4aRW9
FbyGd/FdgqT+Oy9L+l1RTGfMK47p9DUsMTxcmagvvVtLG6QOzLI81SJrhZrQIDPQ
6HorDaM67DnhdNPZFQmkU7ZJWfMU4hQ7XXve7xIj4C4gHaIGJSuIiCbAY+bQFCyV
FwIDAQABo0IwQDAdBgNVHQ4EFgQUBDid1p2ymzsG5zqsUyV5WTWr1GkwHwYDVR0j
BBgwFoAUvR9rQ7nZNbRppsFuFDZJfPhzXAswDQYJKoZIhvcNAQELBQADggEBAHoc
LgNJs84s+Y+MFHUtHT8Wx1HBPM0rdG9yMoEl/AF71sVFBDUmRp2P8bE43ehuGDnt
eRc4o3OLCGTH5QUw1PfY+0HNN9b7xh3NqyhbcDmaFsni8/lzYfycN4kqoOK54Lzm
R1lZZuJn+dArtsx/6QQ+xzxXU0txi7noNhqDHWVDlvYE1mDskhWnd1BkzENYCmA2
8SjDhfpddooqJkC61yzyiR9TlMbNz/k+s8hui1c5Wr7aYziivq9FA7H0owFMaNEP
9XjL3EI/W97zRG6VSQcnba1BFQNqeOcZx6v5O+OzdlrRm+7lAMBQGVOB9hRJxct/
TutBTMH1+BYCuOCoJfo=
-----END CERTIFICATE-----
)";

View File

@ -1,24 +0,0 @@
-----BEGIN CERTIFICATE-----
MIID+jCCAuKgAwIBAgIUeE21DpxD/pqYPrbpPguKo9mpQKswDQYJKoZIhvcNAQEL
BQAwgZMxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
cmxpbjEcMBoGA1UECgwTVGhlIFF0IENvbXBhbnkgR21iSDEMMAoGA1UECwwDUiZE
MRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEWE2Rlbm5pcy5vYmVy
c3RAcXQuaW8wIBcNMjUwMjA0MDgzMjQxWhgPMjEyNTAxMTEwODMyNDFaMIGTMQsw
CQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xHDAa
BgNVBAoME1RoZSBRdCBDb21wYW55IEdtYkgxDDAKBgNVBAsMA1ImRDESMBAGA1UE
AwwJbG9jYWxob3N0MSIwIAYJKoZIhvcNAQkBFhNkZW5uaXMub2JlcnN0QHF0Lmlv
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxEolKk0gnBX1vm+elF/d
tja7zqCXZWwz0/SlR77WhURLvkwYgMEAa2ZIKRaOObAMH83XO+0dczJOND/kT6z1
TblC5+3r9K/GnRi/1tJGKHKRDaIJqXl6d+lmkEm5ToLIjTMqhctxHfuaqletoe0u
kTY8m1xDG7UaSdIQvttXA8JqT5WDAl79Y+OnXXRxnYIEzOqSICNgzW4KP3i4aRW9
FbyGd/FdgqT+Oy9L+l1RTGfMK47p9DUsMTxcmagvvVtLG6QOzLI81SJrhZrQIDPQ
6HorDaM67DnhdNPZFQmkU7ZJWfMU4hQ7XXve7xIj4C4gHaIGJSuIiCbAY+bQFCyV
FwIDAQABo0IwQDAdBgNVHQ4EFgQUBDid1p2ymzsG5zqsUyV5WTWr1GkwHwYDVR0j
BBgwFoAUvR9rQ7nZNbRppsFuFDZJfPhzXAswDQYJKoZIhvcNAQELBQADggEBAHoc
LgNJs84s+Y+MFHUtHT8Wx1HBPM0rdG9yMoEl/AF71sVFBDUmRp2P8bE43ehuGDnt
eRc4o3OLCGTH5QUw1PfY+0HNN9b7xh3NqyhbcDmaFsni8/lzYfycN4kqoOK54Lzm
R1lZZuJn+dArtsx/6QQ+xzxXU0txi7noNhqDHWVDlvYE1mDskhWnd1BkzENYCmA2
8SjDhfpddooqJkC61yzyiR9TlMbNz/k+s8hui1c5Wr7aYziivq9FA7H0owFMaNEP
9XjL3EI/W97zRG6VSQcnba1BFQNqeOcZx6v5O+OzdlrRm+7lAMBQGVOB9hRJxct/
TutBTMH1+BYCuOCoJfo=
-----END CERTIFICATE-----

View File

@ -5,6 +5,7 @@
#include "chatmessages.pb.h"
#include "qtgrpcchat.grpc.pb.h"
#include "credentials/certificates.h"
#include <grpc++/grpc++.h>
#include <grpc++/security/server_credentials.h>
@ -17,7 +18,6 @@
#include <memory>
#include <mutex>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
@ -38,18 +38,6 @@ std::istream &operator>>(std::istream &is, chat::Credentials &u)
return is;
}
std::string readFromFile(const std::string &path)
{
std::ifstream file(path);
if (!file.is_open()) {
std::cerr << "Failed to open " << path << '\n';
std::terminate();
}
std::stringstream ss;
ss << file.rdbuf();
return ss.str();
}
} // namespace
class QtGrpcChatService;
@ -374,8 +362,8 @@ int main(int /* argc */, char * /* argv */[])
//! [server-ssl]
grpc::SslServerCredentialsOptions sslOpts;
sslOpts.pem_key_cert_pairs.emplace_back(grpc::SslServerCredentialsOptions::PemKeyCertPair{
readFromFile(SERVER_DIR "/credentials/localhost.key"),
readFromFile(SERVER_DIR "/credentials/localhost.crt"),
LocalhostKey,
LocalhostCert,
});
builder.AddListeningPort(QtGrpcChatService::httpsAddress(), grpc::SslServerCredentials(sslOpts));
builder.AddListeningPort(QtGrpcChatService::httpAddress(), grpc::InsecureServerCredentials());