Skip to content

Commit

Permalink
Merge pull request #130 from ggtakec/fix_nss
Browse files Browse the repository at this point in the history
Changed handling certificates for NSS and updated dependencies
  • Loading branch information
ggtakec committed Sep 29, 2023
2 parents efec1c7 + 595303d commit f2aacc0
Show file tree
Hide file tree
Showing 7 changed files with 802 additions and 338 deletions.
8 changes: 4 additions & 4 deletions buildutils/chmpx.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ License: @PKGLICENSE@
@RPMPKG_GROUP@
URL: https://@GIT_DOMAIN@/@GIT_ORG@/@PACKAGE_NAME@
Source0: https://@GIT_DOMAIN@/@GIT_ORG@/@PACKAGE_NAME@/archive/%{gittag}/%{name}-%{version}.tar.gz
Requires: k2hash%{?_isa} >= 1.0.74, libfullock%{?_isa} >= 1.0.36
Requires: k2hash%{?_isa} >= 1.0.89, libfullock%{?_isa} >= 1.0.53, nss-tools
%if 0%{?rhel} == 6
BuildRequires: git-core gcc-c++ make libtool k2hash-devel >= 1.0.74, libfullock-devel >= 1.0.36, libyaml-devel, nss-devel
BuildRequires: git-core gcc-c++ make libtool k2hash-devel >= 1.0.89, libfullock-devel >= 1.0.53, libyaml-devel, nss-devel
%else
BuildRequires: systemd git-core gcc-c++ make libtool k2hash-devel >= 1.0.74, libfullock-devel >= 1.0.36, libyaml-devel, nss-devel
BuildRequires: systemd git-core gcc-c++ make libtool k2hash-devel >= 1.0.89, libfullock-devel >= 1.0.53, libyaml-devel, nss-devel
%endif

%description
Expand Down Expand Up @@ -134,7 +134,7 @@ rm -rf %{buildroot}
#
%package devel
Summary: @SHORTDESC@ (development)
Requires: %{name}%{?_isa} = %{version}-%{release}, k2hash-devel%{?_isa} >= 1.0.74, libfullock-devel%{?_isa} >= 1.0.36, libyaml-devel, nss-devel
Requires: %{name}%{?_isa} = %{version}-%{release}, k2hash-devel%{?_isa} >= 1.0.89, libfullock-devel%{?_isa} >= 1.0.53, libyaml-devel, nss-devel

%description devel
Development package for building with @PACKAGE_NAME@ shared library.
Expand Down
6 changes: 3 additions & 3 deletions buildutils/control.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Source: @PACKAGE_NAME@
Section: net
Priority: optional
Maintainer: @DEV_NAME@ <@DEV_EMAIL@>
Build-Depends: @DEBHELPER_DEP@, k2hash-dev (>= 1.0.74), libfullock-dev (>= 1.0.36), libyaml-dev, gnutls-dev
Build-Depends: @DEBHELPER_DEP@, k2hash-dev (>= 1.0.89), libfullock-dev (>= 1.0.53), libyaml-dev, gnutls-dev
Standards-Version: 3.9.8
Homepage: https://@GIT_DOMAIN@/@GIT_ORG@/@GIT_REPO@
Vcs-Git: git://@GIT_DOMAIN@/@GIT_ORG@/@[email protected]
Expand All @@ -11,14 +11,14 @@ Vcs-Browser: https://@GIT_DOMAIN@/@GIT_ORG@/@GIT_REPO@
Package: @PACKAGE_NAME@-dev
Section: devel
Architecture: amd64
Depends: ${misc:Depends}, @PACKAGE_NAME@ (= ${binary:Version}), k2hash-dev (>= 1.0.74), libfullock-dev (>= 1.0.36), libyaml-dev, gnutls-dev
Depends: ${misc:Depends}, @PACKAGE_NAME@ (= ${binary:Version}), k2hash-dev (>= 1.0.89), libfullock-dev (>= 1.0.53), libyaml-dev, gnutls-dev
Description: @SHORTDESC@ (development)
Development package for building with @PACKAGE_NAME@ shared library.
This package has header files and symbols for it.

Package: @PACKAGE_NAME@
Section: net
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}, init-system-helpers (>= 1.14), k2hash (>= 1.0.74), libfullock (>= 1.0.36)
Depends: ${shlibs:Depends}, ${misc:Depends}, init-system-helpers (>= 1.14), k2hash (>= 1.0.89), libfullock (>= 1.0.53)
Description: @SHORTDESC@
@DEBLONGDESC@
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ AC_ARG_ENABLE(check-depend-libs,
esac]
)
AS_IF([test ${check_depend_libs} = 1], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])
AS_IF([test ${check_depend_libs} = 1], [PKG_CHECK_MODULES([k2hash], [libk2hash >= 1.0.74], [], [AC_MSG_ERROR(not found k2hash package)])])
AS_IF([test ${check_depend_libs} = 1], [PKG_CHECK_MODULES([fullock], [libfullock >= 1.0.36], [], [AC_MSG_ERROR(not found libfullock package)])])
AS_IF([test ${check_depend_libs} = 1], [PKG_CHECK_MODULES([k2hash], [libk2hash >= 1.0.89], [], [AC_MSG_ERROR(not found k2hash package)])])
AS_IF([test ${check_depend_libs} = 1], [PKG_CHECK_MODULES([fullock], [libfullock >= 1.0.53], [], [AC_MSG_ERROR(not found libfullock package)])])

#
# CFLAGS/CXXFLAGS
Expand Down
10 changes: 5 additions & 5 deletions lib/chmeventsock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,11 @@ ChmEventSock::ChmEventSock(int eventqfd, ChmCntrl* pcntrl, bool is_ssl) :
if(!pImData->GetSelfSsl(ssldata)){
ERR_CHMPRN("Failed to get SSL structure from self chmpx, but continue...");
}else{
// For only NSS now
if(pImData->GetNssdbDir() && !ChmSecureSock::SetExtValue(CHM_NSS_NSSDB_DIR_KEY, pImData->GetNssdbDir())){
ERR_CHMPRN("Failed to set %s to ChmSecureSock class variable, but continue...", CHM_NSS_NSSDB_DIR_KEY);
}

// cppcheck-suppress noOperatorEq
// cppcheck-suppress noCopyConstructor
pSecureSock = new ChmSecureSock((!ssldata.is_ca_file ? ssldata.capath : NULL), (ssldata.is_ca_file ? ssldata.capath : NULL), ssldata.verify_peer);
Expand All @@ -1871,11 +1876,6 @@ ChmEventSock::ChmEventSock(int eventqfd, ChmCntrl* pcntrl, bool is_ssl) :
if(!ChmSecureSock::SetSslMinVersion(pImData->GetSslMinVersion())){
ERR_CHMPRN("Failed to set SSL/TLS minimum version to ChmSecureSock class variable, but continue...");
}

// For only NSS now
if(pImData->GetNssdbDir() && !ChmSecureSock::SetExtValue(CHM_NSS_NSSDB_DIR_KEY, pImData->GetNssdbDir())){
ERR_CHMPRN("Failed to set %s to ChmSecureSock class variable, but continue...", CHM_NSS_NSSDB_DIR_KEY);
}
}
}

Expand Down
123 changes: 84 additions & 39 deletions lib/chmssnss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ using namespace std;
//
// Symbols
//
// [NOTE]
// CHM_NSS_CERT_PRIKEY_SLOT_STR is the Slot name used when the PEM module
// is loaded and dynamically generated.
// The existing Slot name is usually "NSS Certificate DB".
//
#define CHM_NSS_ENV_CERT_DIR "SSL_DIR"
#define CHM_NSS_DEFAULT_CERT_DIR "/etc/pki/nssdb"
#define CHM_NSS_PKCS11_MODULE_CONF "library=libnssckbi.so name=\"Root Certs\"" // or "library=libnssckbi.so name=trust"
Expand Down Expand Up @@ -721,7 +726,7 @@ bool ChmSecureSock::SetExtValue(const char* key, const char* value)
bool ChmSecureSock::LoadCACerts(chmpk11list_t& pk11objlist)
{
if(!ChmSecureSock::PEM_LoadedModule){
MSG_CHMPRN("CHMPX does not load PEM load module, then we could not load CA cert files(directory), but continue...");
DMP_CHMPRN("PEM load module is not loaded, so CA certs are not loaded dynamically and are used in NSSDB as default.");
return true;
}
PK11GenericObject* pPk11Obj = NULL;
Expand Down Expand Up @@ -841,17 +846,23 @@ bool ChmSecureSock::MakeNickname(const char* pCertFile, string& strNickname)
if(CHMEMPTYSTR(pCertFile)){
return false;
}
if(is_file_safe_exist_ex(pCertFile, false)){
strNickname = CHM_NSS_CERT_PRIKEY_SLOT_STR;
strNickname += ':';

const char* filename = strrchr(pCertFile, '/');
if(!filename){
strNickname += pCertFile;
if(ChmSecureSock::PEM_LoadedModule){
if(is_file_safe_exist_ex(pCertFile, false)){
strNickname = CHM_NSS_CERT_PRIKEY_SLOT_STR;
strNickname += ':';

const char* filename = strrchr(pCertFile, '/');
if(!filename){
strNickname += pCertFile;
}else{
strNickname += ++filename;
}
}else{
strNickname += ++filename;
strNickname = pCertFile;
}
}else{
DMP_CHMPRN("CHMPX does not load PEM load module, so do not use nickname.");
strNickname = pCertFile;
}
return true;
Expand Down Expand Up @@ -899,6 +910,12 @@ bool ChmSecureSock::LoadCertPrivateKey(const char* pCertFile, const char* pPriva
return false;
}

// [NOTE]
// We will differentiate between cases where Nickname is available(PEM module is loaded)
// and cases where Nickname is not available.
// If a certificate is specified and the PEM module is present, you can dynamically create
// the certificate. This is mainly the case for CentOS7.
//
if(0 != strcmp(strNickName.c_str(), pCertFile)){
// Case: pCertFile is existed file.
//
Expand Down Expand Up @@ -932,7 +949,7 @@ bool ChmSecureSock::LoadCertPrivateKey(const char* pCertFile, const char* pPriva
}

}else{
// Case: pCertFile is nickname
// Case: pCertFile is CN(common name)
//
if(CHMEMPTYSTR(pPrivateKeyFile)){
// This case is only cert for nickname in nssdb.
Expand All @@ -951,61 +968,89 @@ bool ChmSecureSock::LoadCertPrivateKey(const char* pCertFile, const char* pPriva
return false;
}
}else{
// This case is some certs for nickname in nssdb.
// Then need to search cert by private key buffer as "issuer:CN" from cert list.
// [NOTE]
// Find the certificate with the target CN(in Subject) from all user certificates.
//
CERTCertList* pCertList;
if(NULL == (pCertList = PK11_FindCertsFromNickname(strNickName.c_str(), NULL))){
ERR_CHMPRN("Failed to call PK11_FindCertsFromNickname" CHM_NSS_ERR_PRN_FORM, CHM_NSS_ERR_PRN_ARGS);

// Debug message for default slot information
if(chm_debug_mode >= CHMDBG_DUMP){
PK11SlotInfo* slot = PK11_GetInternalKeySlot();
if(slot){
DMP_CHMPRN("Found default slot : token name=\"%s\", can use=%s", PK11_GetTokenName(slot), (PK11_IsPresent(slot) ? "yes" : "no"));
PK11_FreeSlot(slot);
}else{
DMP_CHMPRN("Not found default slot");
}
}

// Get user cert list
if(NULL == (pCertList = PK11_ListCerts(PK11CertListAll, NULL))){
ERR_CHMPRN("Failed to call PK11_ListCerts" CHM_NSS_ERR_PRN_FORM, CHM_NSS_ERR_PRN_ARGS);
return false;
}

// search target cert
// Search target cert in list
for(CERTCertListNode* node = CERT_LIST_HEAD(pCertList); !CERT_LIST_END(node, pCertList); node = CERT_LIST_NEXT(node)){
CERTCertificate* pTmpCert = node->cert;
char* pTmpPos;
char* pIssuer;
char* pCN;
char* pSubject;
char* pIssuerCN;
char* pSubjectCN;

if(!pTmpCert){
WAN_CHMPRN("The cert object in cert list is NULL, thus skip it.");
continue;
}

// get "issuer" as Ascii
// Get Issuer's CN (only for debug messages)
if(NULL == (pIssuer = CERT_NameToAscii(&(pTmpCert->issuer)))){
MSG_CHMPRN("The cert object's issuer string in cert list is NULL, thus skip it.");
continue;
}
if(NULL == (pIssuerCN = strstr(pIssuer, CHM_NSS_CN_KEY_IN_ISSUER))){
MSG_CHMPRN("Not found %s key in the cert object's issuer string(%s), thus skip it.", CHM_NSS_CN_KEY_IN_ISSUER, pIssuer);
PR_Free(pIssuer);
continue;
}
pIssuerCN += strlen(CHM_NSS_CN_KEY_IN_ISSUER);

// check "CN="
if(NULL != (pCN = strstr(pIssuer, CHM_NSS_CN_KEY_IN_ISSUER))){
pCN += strlen(CHM_NSS_CN_KEY_IN_ISSUER);

// compare CN string
if(0 == strncmp(pCN, pPrivateKeyFile, strlen(pPrivateKeyFile))){
pCN += strlen(pPrivateKeyFile);

// check end of string
if('\0' == pCN[0] || ',' == pCN[0]){
// found
pCert = CERT_DupCertificate(pTmpCert);
PR_Free(pIssuer);
break;
}else{
MSG_CHMPRN("The cert object's issuer:CN string in cert list is not as same as \"%s\" key, thus skip it.", pPrivateKeyFile);
}
}else{
MSG_CHMPRN("The cert object's issuer:CN string in cert list is not as same as \"%s\" key, thus skip it.", pPrivateKeyFile);
}
}else{
MSG_CHMPRN("The cert object's issuer string in cert list does not have \"%s\" key, thus skip it.", CHM_NSS_CN_KEY_IN_ISSUER);
// Get Subject's CN
if(NULL == (pSubject = CERT_NameToAscii(&(pTmpCert->subject)))){
MSG_CHMPRN("The cert object's subject string in cert list is NULL, thus skip it.");
PR_Free(pIssuer);
continue;
}
if(NULL == (pSubjectCN = strstr(pSubject, CHM_NSS_CN_KEY_IN_ISSUER))){
MSG_CHMPRN("Not found %s key in the cert object's subject string(%s), thus skip it.", CHM_NSS_CN_KEY_IN_ISSUER, pSubject);
PR_Free(pIssuer);
PR_Free(pSubject);
continue;
}
pSubjectCN += strlen(CHM_NSS_CN_KEY_IN_ISSUER);
if(NULL != (pTmpPos = strchr(pSubjectCN, ','))){ // Cut after ','
*pTmpPos = '\0';
}

// compare Subject's CN string and target name
if(0 == strcmp(pSubjectCN, pPrivateKeyFile)){
// found target cert
MSG_CHMPRN("Found the cert(%s) which has issuer CN(%s) and Subject CN(%s).", pPrivateKeyFile, pIssuerCN, pSubjectCN);
pCert = CERT_DupCertificate(pTmpCert);
PR_Free(pIssuer);
PR_Free(pSubject);
break;
}
PR_Free(pIssuer);
PR_Free(pSubject);
}

// free
CERT_DestroyCertList(pCertList);

if(!pCert){
ERR_CHMPRN("Could not find cert in cert list by nickname.");
ERR_CHMPRN("Could not find target cert in cert list.");
return false;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ EXTRA_DIST = test.sh \
cfg_test_slave.yaml \
cfg_test_json_string.data

dist_bin_SCRIPTS = chmpxnssutil.sh

#
# Local variables:
# tab-width: 4
Expand Down
Loading

0 comments on commit f2aacc0

Please sign in to comment.