Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion certainly.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ certainly(1) -- create self-signed certificates with ease

## SYNOPSIS

certainly [`--std` | `--double-std`] [`--ca` <name>] <domain> [<domain>...]
certainly [`--std` | `--double-std`] [`--ca` <name>] [`--client`] <domain> [<domain>...]

certainly [`--std` | `--double-std`] `--make-ca` <name>

Expand Down Expand Up @@ -32,6 +32,9 @@ Outputs first the key then the certificate to STDOUT.
* `--double-std`:
Outputs the key to STDERR, and the certificate to STDOUT. This is useful to write both files to a custom location efficiently, such as: `certainly --double-std domain.test > test.crt 2> test.key`.

* `--client`:
Creates a client certificate instead of a server certificate.

* `--ca` <name>:
Uses the certificate/key pair _<name>.crt_ and _<name>.key_ to sign the created certificate instead of self-signing.

Expand Down
27 changes: 23 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use openssl::nid::Nid;
use openssl::pkey::{PKey, PKeyRef, Private};
use openssl::ssl::{HandshakeError, SslConnector, SslMethod, SslVerifyMode};
use openssl::x509::extension::{
AuthorityKeyIdentifier as AuthKey, BasicConstraints, KeyUsage, SubjectAlternativeName,
SubjectKeyIdentifier as SubjectKey,
AuthorityKeyIdentifier as AuthKey, BasicConstraints, KeyUsage, ExtendedKeyUsage,
SubjectAlternativeName, SubjectKeyIdentifier as SubjectKey,
};
use openssl::x509::{X509, X509Builder, X509NameBuilder, X509Ref};
use std::fs::{File, OpenOptions};
Expand Down Expand Up @@ -94,6 +94,11 @@ fn main() -> Result<(), Ernum> {
.value_name("NAME")
.help("Create a CA cert and key suitable for signing"),
)
.arg(
Arg::with_name("client")
.long("client")
.help("Create a client certificate instead of a server one"),
)
.arg(
Arg::with_name("ca")
.long("ca")
Expand Down Expand Up @@ -137,9 +142,13 @@ fn main() -> Result<(), Ernum> {
let caname = args.value_of("ca").unwrap();
let cakey = load_key(format!("{}.key", caname).into())?;
let cacrt = load_cert(format!("{}.crt", caname).into())?;
create(doms, Some((cakey.as_ref(), cacrt.as_ref())))?
create(
doms,
Some((cakey.as_ref(), cacrt.as_ref())),
args.is_present("client"),
)?
} else {
create(doms, None)?
create(doms, None, args.is_present("client"))?
}
};

Expand Down Expand Up @@ -241,6 +250,7 @@ fn makeca(name: &str) -> Result<(Vec<u8>, Vec<u8>), Ernum> {
fn create(
domains: Vec<&str>,
ca: Option<(&PKeyRef<Private>, &X509Ref)>,
is_client: bool,
) -> Result<(String, Vec<u8>, Vec<u8>), Ernum> {
let name = domains[0];
let mut cert = base_cert(name, ca)?;
Expand All @@ -255,6 +265,15 @@ fn create(
.build()?,
)?;

let mut ekr = ExtendedKeyUsage::new();
if is_client {
ekr.client_auth();
} else {
ekr.server_auth();
}
let ekr = ekr.build()?;
cert.append_extension(ekr)?;

let mut san = SubjectAlternativeName::new();
for dom in domains {
san.dns(dom);
Expand Down