Add commands to publish certificate to a different location after signing
Hello, a pull-request to add a 'publish' feature to easy-rsa.
The rational is as follows: I use easy-rsa at two locations, lets call them SHARED and PRIVATE. SHARED is used to generate request and to publish the results, it does not contains a CA. It can be accessed/mounted to install the certificate on the servers or client. PRIVATE contains the CA certificate. PRIVATE can access SHARED but nothing else, it does not have network access. The commands added in this set of commit help handle this case.
A typical usage is:
In SHARED run: easy-rsa gen-req my_server In PRIVATE set the variable EASYRSA_PUBLISH to SHARED and run: easy-rsa import-req my_server easy-rsa sign server my_server easy-rsa publish-ca update Then SHARED contains all the needed files but not the private key of the CA.
The pull-request also contains two patch not directly related to the feature, tell me if you prefer to have separate pull-requests for them instead.
Best Regards,
Julien VdG
I like this idea, but I'm not sure it belongs within Easy-RSA itself. This sounds more like a wrapper function.
I know, I first planned to do it as a wrapper script, but this was a lot of redoing the same logic as in Easy-RSA to configure folders to manage commands and so on. So I ended up adding it to Easy-RSA proper and doing a wrapper script for functions that really are more 'batch' use (see https://github.com/JulienVdG/raspki/blob/master/overlay/usr/bin/raspki ). So I tried to write it with configuration variables so that basic usage is not modified.
But I can understand if you don't want to integrate it as it means you'll have to maintain it for ever after... I'll keep my fork for my own use.
Best regards, JulienVdG
My concern is mostly due to cross platform functionality. This is a feature that would work well on Linux but doesn't scale to Windows.
If it worked on both I'd happily include it in base.
Eric Crist
On Jul 2, 2017, at 3:08 AM, Julien Viard de Galbert [email protected] wrote:
I know, I first planned to do it as a wrapper script, but this was a lot of redoing the same logic as in Easy-RSA to configure folders to manage commands and so on. So I ended up adding it to Easy-RSA proper and doing a wrapper script for functions that really are more 'batch' use (see https://github.com/JulienVdG/raspki/blob/master/overlay/usr/bin/raspki ). So I tried to write it with configuration variables so that basic usage is not modified.
But I can understand if you don't want to integrate it as it means you'll have to maintain it for ever after... I'll keep my fork for my own use.
Best regards, JulienVdG
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
Oh, so you're asking to test and fix it on Windows before a possible integration. That's fair.
By reviewing my patches (I don't have windows to test here) I think only the last one "Add status command..." looks non portable.
By reviewing my patches (I don't have windows to test here) I think only the last one "Add status command..." looks non portable.
Is this in a ready-state? If so, I'll review it.
Well I didn't test it on windows - I only tried with a previous release where the windows binary were missing so I failed. But as md5sum is part of the added binaries, I think even the Status command will work on windows... Again, I didn't test it on windows yet so no guaranties on that front. And I really don't know when I'll find time and motivation to boot windows :)
Hello,
I started to rebase on 3.0.5 release.
I wanted to do my first tests on windows, (last year I tested on the release that missed the binaries...) but it does not seam to work... I'm getting an error: "cannot create /dev/null: Invalid argument"
The sh.exe binary is a release (or a preview?) from 2013 !! None of the binaries have proper source or link to actual source (only name of project and mksh/win32 does not seam to exist anymore or I couldn't find the webpage).
Do you still really want to support windows ?
To be fair, I tested on a fresh install of ReactOS (because I don't have any windows at hand)
Then I installed git (https://gitforwindows.org/) and using git bash I could launch bin/easyrsa-shell-init.sh so I'll be able to test, but not with the provided binaries ... so is there any point ?
~~I use this for Windows testing: https://sites.google.com/site/easylinuxtipsproject/oldgrub~~
Better late than never ! I found time to rebase all this :tada:
I'm out of town for the rest of October, but will look into this and pull it in if it looks good when I return.
IMHO this should be a wrapper script.
If you do this on your own independent repo then you have full control.
As a wrapper script it would duplicate a lot of easyrsa's code, I also use a wrapper for more features but this was better here... Anyway I understand, and won't probably have time to update this soon so I agree with the maybe-someday tag !
As I understand it, your essential goal is to publish public and private data to different places but EasyRSA does not provide a suitable structure.
I'll take a closer look some time but for now, this is not a priority.
Something brewing ..
Required:
$EASYRSA_ISSUED: Option--issued=<DIR>[Not in PKI]
Insert $EASYRSA_ISSUED where required. eg. build-ca
Hello I did a simple rebase of my old code. I think you have other ideas on how to implement this feature, so it might not be that useful. Anyway there are a few commits in there that are not completely related to the main feature (they should probably be split out of this MR but I had enough rebase conflicts for today :smile: ) so I'm trying to keep my branch up to date with easyrsa from time to time.
Oh I think I just got the $EASYRSA_ISSUED idea:
You propose to make the pki/issued directory configurable so that easyrsa can write the output directly outside of the pki directory.
While my approach was to copy the issued files to the external directory with a new command.
Is that so ?
You propose to make the pki/issued directory configurable so that easyrsa can write the output directly outside of the pki directory.
Exactly. However, that is not set in stone.
Your approach still has merit, in that the standard PKI remains intact.
FYI: This PR requires a signature. Also, I prefer that PRs use a new branch, not master. We can sort those issues out in time.
@JulienVdG I prefer your approach of the new command: publish-cert
There are some things that I'm not keen on though..
@JulienVdG Can you explain what value there is to you by stripping the certificate text output ?
@JulienVdG Can you explain what value there is to you by stripping the certificate text output ?
Some software will fail to read the certificate if there is anything but the -----HEADER / FOOTER----- and the base64 cert data. Off the top of my head, some asn1 parsers including "openssl asn1parse".
@JulienVdG Can you explain what value there is to you by stripping the certificate text output ?
Some software will fail to read the certificate if there is anything but the -----HEADER / FOOTER----- and the base64 cert data. Off the top of my head, some asn1 parsers including "openssl asn1parse".
I have reopened #624 in order to reconsider this problem.
Adding a single option to building a certificate without the public/human readable text appears to be the most logical solution.
Due to renew and all that, it may be desirable to have an easyrsa built-in function to out put a bare-bones certificate. PRs may be welcome for such a function.
eg: strip_cert() .. type of thing.
Adding a single option to building a certificate without the public/human readable text appears to be the most logical solution.
Due to
renewand all that, it may be desirable to have aneasyrsabuilt-in function to out put a bare-bones certificate. PRs may be welcome for such a function.eg:
strip_cert().. type of thing.
I'd prefer this strip_cert() idea.
For my workflow I like having the easyrsa/pki certs with the cert text included: I can read basename.crt OR serial.crt with a pager / tail / cat and know what the cert was. I'm still not sure what service I am (or was) running that barfed on cert text in the cert bundle.
Please, keep in mind that strip_cert() (Or a better name) is probably plumbing not porcelain. It needs to be an option that could work with an existing certificate but probably not over-write the source. Building a new certificate can be bare-bones because it is the source file.
what is the purpose of easyrsa3/x509-types/COMMON-SECTIONS ?
easyrsa currently has no means to handle raw extensions. If raw extension support was added it would need to be specifically added to the end of generated temporary extension file.
The COMMON-SECTIONS as written looks as though basicConstraints, kU, eKU from the other x509-types/foo would be appended to that [ crlDistributionPoints_values ] section which would not be what a user wants.
It might be a nice-to-have if publish_ca() had some means to prep for a ca-bundle: i.e. that successive easyrsa publish-ca from the rootCA through subCAs would enable one to have a cachain.crt available at the working (non-ca) easyrsa/pki location
@dekeonus Hi :-)
I have an alternative version to this "publishing" branch (To be pushed), which is only concerned with copying files to the public folder.
The other details are not relevant to this PR, they are only included as part of @JulienVdG source (Which is also from his master and, therefore, unacceptable as a genuine PR. Further details are here).
This PR also remains unsigned. As it should remain.
Draft diff:
diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa
index a0e5652..eafe44b 100755
--- a/easyrsa3/easyrsa
+++ b/easyrsa3/easyrsa
@@ -3031,6 +3031,89 @@ location: $pkcs_out"
return 0
} # => export_pkcs()
+# Publish a file
+# Required parameters:
+# 1: Full source directory. eg: /etc/easy-rsa/pki/issued
+# 2: Source File name. eg: server.crt
+# 3: Destination File name. Optional. eg: other-name.crt
+publish_file() {
+ # Public directory must exist
+ if [ "$EASYRSA_PUBLIC" ]; then
+ mkdir -p "$EASYRSA_PUBLIC" || die "\
+publish_file - Public directory access violation: '$EASYRSA_PUBLIC'"
+ else
+ die "\
+publish_file - Public directory undefined."
+ fi
+
+ # Source directory must be specified and exist
+ source_d="$1"; shift || die "\
+publish_file - Missing input: 'source_d'"
+ [ -d "$source_d" ] || die "\
+publish_file - Source directory missing: '$source_d'"
+
+ # Input file name must be specified and exist
+ name_in="$1"; shift || die "\
+publish_file - Missing input: 'name_in'"
+ file_in="${source_d}/${name_in}"
+ [ -f "$file_in" ] || die "\
+publish_file - Source file missing: '$file_in'"
+
+ # Output file can be renamed
+ if [ "$1" ]; then
+ file_out="${EASYRSA_PUBLIC}/$1"
+ else
+ file_out="${EASYRSA_PUBLIC}/${name_in}"
+ fi
+ file_out_tmp="${file_out}.easyrsa-temp"
+
+ # Verify input file
+ # TODO
+ # "strip" input file.. TODO
+
+ # Copy input to temporary output
+ if cp "$file_in" "$file_out_tmp"; then
+ # Over write any other file of the same output name
+ if mv -f "$file_out_tmp" "$file_out"; then
+ notice "\
+File successfully published to:
+* $file_out"
+ else
+ rm -f "$file_out_tmp"
+ die "\
+publish_file - Failed to publish file: '$file_in'"
+ fi
+ else
+ rm -f "$file_out_tmp"
+ die "\
+publish_file - Failed to copy source file to public directory."
+ fi
+} # => publish_file()
+
+# Publish certificate
+publish_cert() {
+ publish_file "$EASYRSA_PKI/issued" "$1.crt" "$2.crt"
+} # => publish_cert()
+
+# Publish CA
+publish_ca() {
+ publish_file "$EASYRSA_PKI" "ca.crt"
+} # => publish_ca()
+
+# Publish CRL
+publish_crl() {
+ # <- gen_crl
+ publish_file "$EASYRSA_PKI" "crl.crt"
+} # => publish_crl()
+
+# Publish for OSCP
+publish_oscp() {
+ # example
+ publish_ca
+ publish_crl
+ # <- update_db
+ publish_file "$EASYRSA_PKI" "index.txt"
+} # => publish_oscp()
+
# set-pass backend
set_pass() {
# Verify PKI has been initialised
@@ -4188,6 +4271,7 @@ Sourcing the vars file and building certificates will probably fail ..'
set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI"
set_var EASYRSA_REQ_CN ChangeMe
set_var EASYRSA_DIGEST sha256
+ set_var EASYRSA_PUBLIC "$EASYRSA_PKI/public"
set_var EASYRSA_SSL_CONF "$EASYRSA_PKI/openssl-easyrsa.cnf"
set_var EASYRSA_SAFE_CONF "$EASYRSA_PKI/safessl-easyrsa.cnf"
@@ -4945,6 +5029,9 @@ while :; do
--tmp-dir)
export EASYRSA_TEMP_DIR="$val"
;;
+ --pub-dir)
+ export EASYRSA_PUBLIC="$val"
+ ;;
--ssl-conf)
export EASYRSA_SSL_CONF="$val"
;;
@@ -5164,6 +5251,23 @@ case "$cmd" in
export-p1)
export_pkcs p1 "$@"
;;
+ publish-ca)
+ publish_ca "$@"
+ ;;
+ publish-crl)
+ publish_crl "$@"
+ ;;
+ publish-oscp)
+ publish_oscp "$@"
+ ;;
+ publish-pkcs)
+ #publish_pkcs "$@"
+ print "Not currently available: publish-pkcs"
+ easyrsa_error_exit=1
+ ;;
+ publish-cert)
+ publish_cert "$@"
+ ;;
set-rsa-pass)
set_pass rsa "$@"
;;
to easily get cert without text, one could extend publish_file() to have an optional (either arg 3 or 4) notext option. (and a corresponding case / if-else [ "file_ext" = "crt" ] to replace cp ... with easyrsa_openssl x509 -in "$file_in" -out "$file_out_tmp" ... )