Skip to content

Commit

Permalink
Added p11-kit-trust for pki CLI
Browse files Browse the repository at this point in the history
The pki CLI has been modified to add the p11-kit-trust module
into the NSS database such that it trusts the CA certificates
provided by the system.
  • Loading branch information
edewata committed Oct 14, 2019
1 parent 5a4352f commit 551af2d
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 59 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ if (NOT DEFINED NSS_DEFAULT_DB_TYPE)
set(NSS_DEFAULT_DB_TYPE "dbm")
endif(NOT DEFINED NSS_DEFAULT_DB_TYPE)

if (NOT DEFINED P11_KIT_TRUST)
set(P11_KIT_TRUST "/usr/lib64/pkcs11/p11-kit-trust.so")
endif(NOT DEFINED P11_KIT_TRUST)

if (NOT DEFINED THEME)
set(VERSION "dogtag")
endif(NOT DEFINED THEME)
Expand Down
1 change: 1 addition & 0 deletions base/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E create_symlink ${SERVLET_JAR} lib/servlet.jar
COMMAND ${CMAKE_COMMAND} -E create_symlink ${SLF4J_API_JAR} lib/slf4j-api.jar
COMMAND ${CMAKE_COMMAND} -E create_symlink ${SLF4J_JDK14_JAR} lib/slf4j-jdk14.jar
COMMAND ln -sf ${P11_KIT_TRUST} lib/p11-kit-trust.so
)

add_custom_target(pki-man ALL
Expand Down
219 changes: 219 additions & 0 deletions base/common/src/org/dogtagpki/nss/NSSDatabase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2019 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---

package org.dogtagpki.nss;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.FileUtils;

/**
* @author Endi S. Dewata
*/
public class NSSDatabase {

public static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(NSSDatabase.class);

File directory;

public NSSDatabase(File directory) {
this.directory = directory;
}

public File getDirectory() {
return directory;
}

public void setDirectory(File directory) {
this.directory = directory;
}

public boolean exists() {
return directory.exists();
}

public void create() throws Exception {
create(null);
}

public void create(String password) throws Exception {

logger.info("Creating NSS database in " + directory);

directory.mkdirs();

File passwordFile = new File(directory, "password.txt");

try {
List<String> command = new ArrayList<>();
command.add("certutil");
command.add("-N");
command.add("-d");
command.add(directory.getAbsolutePath());

if (password == null) {
command.add("--empty-password");

} else {
try (PrintWriter out = new PrintWriter(new FileWriter(passwordFile))) {
out.println(password);
}

command.add("-f");
command.add(passwordFile.getAbsolutePath());
}

debug(command);

ProcessBuilder pb = new ProcessBuilder(command);
pb.inheritIO();

Process p = pb.start();
int rc = p.waitFor();

if (rc != 0) {
throw new Exception("Command failed: rc=" + rc);
}

} finally {
if (passwordFile.exists()) passwordFile.delete();
}

// Install p11-kit-trust module if it doesn't exist
if (!isModuleInstalled("p11-kit-trust")) {
addModule("p11-kit-trust", "/usr/share/pki/lib/p11-kit-trust.so");
}
}

public boolean isModuleInstalled(String name) throws Exception {

logger.info("Checking module " + name);

List<String> command = new ArrayList<>();
command.add("modutil");
command.add("-dbdir");
command.add(directory.getAbsolutePath());
command.add("-rawlist");

debug(command);

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);

Process p = pb.start();

// searching for name="<module>"
String pattern = " name=\"" + name + "\" ";

try (Reader reader = new InputStreamReader(p.getInputStream());
BufferedReader in = new BufferedReader(reader)) {

String line;
while ((line = in.readLine()) != null) {
if (line.contains(pattern)) return true;
}
}

int rc = p.waitFor();

if (rc != 0) {
throw new Exception("Command failed: rc=" + rc);
}

return false;
}

public void addModule(String name, String library) throws Exception {

logger.info("Installing " + name + " module with " + library);

List<String> command = new ArrayList<>();
command.add("modutil");
command.add("-dbdir");
command.add(directory.getAbsolutePath());
command.add("-add");
command.add(name);
command.add("-libfile");
command.add(library);
command.add("-force");

debug(command);

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);

Process p = pb.start();

try (Writer writer = new OutputStreamWriter(p.getOutputStream());
PrintWriter out = new PrintWriter(writer)) {

// modutil will generate the following question:

// WARNING: Manually adding a module while p11-kit is enabled could cause
// duplicate module registration in your security database. It is suggested
// to configure the module through p11-kit configuration file instead.
//
// Type 'q <enter>' to abort, or <enter> to continue:

// respond with <enter>
out.println();
}

int rc = p.waitFor();

if (rc != 0) {
throw new Exception("Command failed: rc=" + rc);
}
}

public void delete() throws Exception {
FileUtils.deleteDirectory(directory);
}

public void debug(Collection<String> command) {

if (logger.isDebugEnabled()) {

StringBuilder sb = new StringBuilder("Command:");

for (String c : command) {

boolean quote = c.contains(" ");

sb.append(' ');

if (quote) sb.append('"');
sb.append(c);
if (quote) sb.append('"');
}

logger.debug(sb.toString());
}
}
}
22 changes: 5 additions & 17 deletions base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.dogtagpki.cli.CLIException;
import org.dogtagpki.common.Info;
import org.dogtagpki.common.InfoClient;
import org.dogtagpki.nss.NSSDatabase;
import org.dogtagpki.util.logging.PKILogger;
import org.dogtagpki.util.logging.PKILogger.Level;
import org.mozilla.jss.CryptoManager;
Expand Down Expand Up @@ -470,24 +471,11 @@ public void init() throws Exception {
return;
}

// Create NSS database if it doesn't exist
if (!certDatabase.exists()) {
NSSDatabase nssdb = new NSSDatabase(certDatabase);

logger.info("Creating NSS database");

certDatabase.mkdirs();

String[] commands = {
"/usr/bin/certutil", "-N",
"-d", certDatabase.getAbsolutePath(),
"--empty-password"
};

try {
runExternal(commands);
} catch (Exception e) {
throw new Exception("Unable to create NSS database", e);
}
if (!nssdb.exists()) {
// Create a default NSS database without password
nssdb.create();
}

logger.info("Initializing NSS");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,11 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.io.FileUtils;
import org.dogtagpki.cli.CommandCLI;
import org.dogtagpki.nss.NSSDatabase;

import com.netscape.certsrv.client.ClientConfig;
import com.netscape.cmstools.cli.MainCLI;
Expand Down Expand Up @@ -65,8 +61,10 @@ public void execute(CommandLine cmd) throws Exception {

MainCLI mainCLI = clientCLI.mainCLI;
File certDatabase = mainCLI.getNSSDatabase();
NSSDatabase nssdb = new NSSDatabase(certDatabase);

if (certDatabase.exists()) {
// Make sure existing NSS database is deleted
if (nssdb.exists()) {

boolean force = cmd.hasOption("force");

Expand All @@ -83,42 +81,11 @@ public void execute(CommandLine cmd) throws Exception {
}
}

FileUtils.deleteDirectory(certDatabase);
nssdb.delete();
}

File passwordFile = new File(certDatabase, "password.txt");

try {
certDatabase.mkdirs();

List<String> command = new ArrayList<>();
command.add("certutil");
command.add("-N");
command.add("-d");
command.add(certDatabase.getAbsolutePath());

ClientConfig config = mainCLI.getConfig();
String password = config.getNSSPassword();

if (password == null) {
command.add("--empty-password");

} else {
try (PrintWriter out = new PrintWriter(new FileWriter(passwordFile))) {
out.println(password);
}

command.add("-f");
command.add(passwordFile.getAbsolutePath());
}

runExternal(command);

} catch (Exception e) {
throw new Exception("Unable to create NSS database: " + e.getMessage(), e);

} finally {
if (passwordFile.exists()) passwordFile.delete();
}
// Create NSS database with the provided password
ClientConfig config = mainCLI.getConfig();
nssdb.create(config.getNSSPassword());
}
}
7 changes: 6 additions & 1 deletion pki.spec
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ Summary: PKI Base Package
BuildArch: noarch

Requires: nss >= 3.36.1
Requires: p11-kit-trust

%if 0%{?with_python3_default}
Requires: python3-pki = %{version}
Requires(post): python3-pki = %{version}
Expand Down Expand Up @@ -1018,6 +1020,7 @@ cd build
--no-warn-unused-cli \
-DVERSION=%{version}-%{release} \
-DVAR_INSTALL_DIR:PATH=/var \
-DP11_KIT_TRUST=/etc/alternatives/libnssckbi.so.%{_arch} \
-DJAVA_HOME=%{java_home} \
-DJAVA_LIB_INSTALL_DIR=%{_jnidir} \
-DSYSTEMD_LIB_INSTALL_DIR=%{_unitdir} \
Expand Down Expand Up @@ -1329,6 +1332,7 @@ fi
%dir %{_datadir}/pki/etc
%{_datadir}/pki/etc/pki.conf
%{_datadir}/pki/etc/logging.properties
%dir %{_datadir}/pki/lib
%dir %{_datadir}/pki/scripts
%{_datadir}/pki/scripts/config
%{_datadir}/pki/upgrade/
Expand Down Expand Up @@ -1363,7 +1367,7 @@ fi
%doc base/common/LICENSE
%doc base/common/LICENSE.LESSER
%{_datadir}/pki/examples/java/
%{_datadir}/pki/lib/
%{_datadir}/pki/lib/*.jar
%dir %{_javadir}/pki
%{_javadir}/pki/pki-cmsutil.jar
%{_javadir}/pki/pki-nsutil.jar
Expand Down Expand Up @@ -1421,6 +1425,7 @@ fi
%{_bindir}/TokenInfo
%{_javadir}/pki/pki-tools.jar
%{_datadir}/pki/java-tools/
%{_datadir}/pki/lib/p11-kit-trust.so
%{_mandir}/man1/AtoB.1.gz
%{_mandir}/man1/AuditVerify.1.gz
%{_mandir}/man1/BtoA.1.gz
Expand Down

0 comments on commit 551af2d

Please sign in to comment.