You've already forked step-ca-cli
mirror of
https://github.com/smallstep/cli.git
synced 2025-08-09 03:22:43 +03:00
Merge branch 'master' into use/crypto
This commit is contained in:
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
|||||||
prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
|
prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
|
||||||
|
|
||||||
goreleaser:
|
goreleaser:
|
||||||
name: Upload Assets to Github w/ goreleaser
|
name: Upload Assets to GitHub w/ goreleaser
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: create_release
|
needs: create_release
|
||||||
steps:
|
steps:
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
version: 'latest'
|
version: 'latest'
|
||||||
args: release --rm-dist
|
args: release --rm-dist
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
GITHUB_TOKEN: ${{ secrets.GORELEASER_PAT }}
|
||||||
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
|
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
|
||||||
RELEASE_DATE: ${{ steps.release_date.outputs.RELEASE_DATE }}
|
RELEASE_DATE: ${{ steps.release_date.outputs.RELEASE_DATE }}
|
||||||
|
|
||||||
@@ -174,20 +174,20 @@ jobs:
|
|||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
repository: smallstep/docs
|
repository: smallstep/docs
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.DOCS_PAT }}
|
||||||
path: './docs'
|
path: './docs'
|
||||||
- name: Update Reference
|
- name: Update Reference
|
||||||
id: update_refrence
|
id: update_reference
|
||||||
run: |
|
run: |
|
||||||
./bin/step help --markdown ./docs/src/pages/docs/step-cli/reference
|
./bin/step help --markdown ./docs/src/pages/docs/step-cli/reference
|
||||||
cd ./docs
|
cd ./docs
|
||||||
git config user.email "eng@smallstep.com"
|
git config user.email "eng@smallstep.com"
|
||||||
git config user.name "Github Action CI"
|
git config user.name "GitHub Action CI"
|
||||||
git add . && git commit -a -m "step-cli ${{ needs.create_release.outputs.vversion }} reference update"
|
git add . && git commit -a -m "step-cli ${{ needs.create_release.outputs.vversion }} reference update"
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
uses: ad-m/github-push-action@v0.6.0
|
uses: ad-m/github-push-action@v0.6.0
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.PAT }}
|
github_token: ${{ secrets.DOCS_PAT }}
|
||||||
branch: 'main'
|
branch: 'main'
|
||||||
directory: './docs'
|
directory: './docs'
|
||||||
repository: 'smallstep/docs'
|
repository: 'smallstep/docs'
|
||||||
|
@@ -169,7 +169,7 @@ release:
|
|||||||
- 📦 [step-cli_{{ .Version }}_amd64.deb](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step-cli_{{ .Version }}_amd64.deb)
|
- 📦 [step-cli_{{ .Version }}_amd64.deb](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step-cli_{{ .Version }}_amd64.deb)
|
||||||
- 📦 [step-cli_{{ .Version }}_amd64.rpm](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step-cli_{{ .Version }}_amd64.rpm)
|
- 📦 [step-cli_{{ .Version }}_amd64.rpm](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step-cli_{{ .Version }}_amd64.rpm)
|
||||||
|
|
||||||
#### OSX Darwin
|
#### macOS Darwin
|
||||||
|
|
||||||
- 📦 [step_darwin_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step_darwin_{{ .Version }}_amd64.tar.gz)
|
- 📦 [step_darwin_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step_darwin_{{ .Version }}_amd64.tar.gz)
|
||||||
- 📦 [step_darwin_{{ .Version }}_arm64.tar.gz](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step_darwin_{{ .Version }}_arm64.tar.gz)
|
- 📦 [step_darwin_{{ .Version }}_arm64.tar.gz](https://dl.step.sm/gh-release/cli/gh-release-header/{{ .Tag }}/step_darwin_{{ .Version }}_arm64.tar.gz)
|
||||||
@@ -212,7 +212,7 @@ release:
|
|||||||
# Defaults to false.
|
# Defaults to false.
|
||||||
#disable: true
|
#disable: true
|
||||||
|
|
||||||
# You can add extra pre-existing files to the release.
|
# You can add extra preexisting files to the release.
|
||||||
# The filename on the release will be the last part of the path (base). If
|
# The filename on the release will be the last part of the path (base). If
|
||||||
# another file with the same name exists, the latest one found will be used.
|
# another file with the same name exists, the latest one found will be used.
|
||||||
# Defaults to empty.
|
# Defaults to empty.
|
||||||
|
@@ -163,11 +163,11 @@ to the value of provisioner-password-file flag.
|
|||||||
|
|
||||||
## [0.0.2]
|
## [0.0.2]
|
||||||
### Added
|
### Added
|
||||||
- `--bundle` flag to cert/inspect for inpecting all the full chain or bundle
|
- `--bundle` flag to cert/inspect for inspecting all the full chain or bundle
|
||||||
given a path. Default behavior is unchanged; only inspect the first (leaf)
|
given a path. Default behavior is unchanged; only inspect the first (leaf)
|
||||||
certificate.
|
certificate.
|
||||||
- distribution.md with documentation on how to create releases.
|
- distribution.md with documentation on how to create releases.
|
||||||
- travis build and upload artifacts to Github Releases on tagged pushes.
|
- travis build and upload artifacts to GitHub Releases on tagged pushes.
|
||||||
- logging of invalid http requests to the oauth server
|
- logging of invalid http requests to the oauth server
|
||||||
### Changed
|
### Changed
|
||||||
- default PEM format encryption alg AES128 -> AES256
|
- default PEM format encryption alg AES128 -> AES256
|
||||||
|
2
Makefile
2
Makefile
@@ -91,7 +91,7 @@ define BUNDLE
|
|||||||
# $(2) -- Binary Output Dir Name
|
# $(2) -- Binary Output Dir Name
|
||||||
# $(3) -- Step Platform Name
|
# $(3) -- Step Platform Name
|
||||||
# $(4) -- Step Binary Architecture
|
# $(4) -- Step Binary Architecture
|
||||||
# $(5) -- Step Binary Name (For Windows Comaptibility)
|
# $(5) -- Step Binary Name (For Windows Compatibility)
|
||||||
$(q) ./make/bundle.sh $(1) "$(BINARY_OUTPUT)$(2)" "$(RELEASE)" "$(VERSION)" "$(3)" "$(4)" "$(5)"
|
$(q) ./make/bundle.sh $(1) "$(BINARY_OUTPUT)$(2)" "$(RELEASE)" "$(VERSION)" "$(3)" "$(4)" "$(5)"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ Step CLI's command groups illustrate its wide-ranging uses:
|
|||||||
|
|
||||||
- [`step certificate`](https://smallstep.com/docs/step-cli/reference/certificate/): Work with X.509 (TLS/HTTPS) certificates.
|
- [`step certificate`](https://smallstep.com/docs/step-cli/reference/certificate/): Work with X.509 (TLS/HTTPS) certificates.
|
||||||
- Create, revoke, validate, lint, and bundle X.509 certificates.
|
- Create, revoke, validate, lint, and bundle X.509 certificates.
|
||||||
- Install (and remove) X.509 certificates into your system's (and brower's) trust store.
|
- Install (and remove) X.509 certificates into your system's (and browser's) trust store.
|
||||||
- Validate certificate deployment and renewal status for automation
|
- Validate certificate deployment and renewal status for automation
|
||||||
- Create key pairs (RSA, ECDSA, EdDSA) and certificate signing requests (CSRs)
|
- Create key pairs (RSA, ECDSA, EdDSA) and certificate signing requests (CSRs)
|
||||||
- [Sign CSRs](https://smallstep.com/docs/step-cli/reference/certificate/sign/)
|
- [Sign CSRs](https://smallstep.com/docs/step-cli/reference/certificate/sign/)
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
## Deprecated
|
## Deprecated
|
||||||
The files in this folder are deprecated and will be removed in the future. The prefered way to acces the completion scripts is through `step completion <shell>`.
|
The files in this folder are deprecated and will be removed in the future. The prefered way to access the completion scripts is through `step completion <shell>`.
|
||||||
|
@@ -79,8 +79,8 @@ required, and ensuring they're printed out as a part of the `step help` or
|
|||||||
`step <command> -h` flow. If you need to add a different type of annotation to
|
`step <command> -h` flow. If you need to add a different type of annotation to
|
||||||
document an argument just add it to the `usage.Argument` struct!
|
document an argument just add it to the `usage.Argument` struct!
|
||||||
|
|
||||||
When you add a flag, look into the pre-existing ones inside the `flags`
|
When you add a flag, look into the preexisting ones inside the `flags`
|
||||||
package. Could you use one of the pre-existing flags in order to reduce
|
package. Could you use one of the preexisting flags in order to reduce
|
||||||
duplication? If not, make sure to add a flag so it could be used in future!
|
duplication? If not, make sure to add a flag so it could be used in future!
|
||||||
|
|
||||||
The `errs` package contains functionality for defining and working with errors
|
The `errs` package contains functionality for defining and working with errors
|
||||||
|
@@ -53,7 +53,7 @@ YWJjMTIzJCVeJiooKV8rLT1-Cg==
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
Decode an url encoded base64 string. The encoding type can be enforced
|
Decode an url encoded base64 string. The encoding type can be enforced
|
||||||
using the '-u' or '-r' flags, but it will be autodetected if they are not
|
using the '-u' or '-r' flags, but it will be auto-detected if they are not
|
||||||
passed:
|
passed:
|
||||||
'''
|
'''
|
||||||
$ echo YWJjMTIzJCVeJiooKV8rLT1-Cg== | step base64 -d
|
$ echo YWJjMTIzJCVeJiooKV8rLT1-Cg== | step base64 -d
|
||||||
|
@@ -74,7 +74,7 @@ $ step ca renew internal.crt internal.key \
|
|||||||
revokeCertificateCommand(),
|
revokeCertificateCommand(),
|
||||||
provisioner.Command(),
|
provisioner.Command(),
|
||||||
signCertificateCommand(),
|
signCertificateCommand(),
|
||||||
rootComand(),
|
rootCommand(),
|
||||||
rootsCommand(),
|
rootsCommand(),
|
||||||
federationCommand(),
|
federationCommand(),
|
||||||
acme.Command(),
|
acme.Command(),
|
||||||
|
@@ -12,7 +12,7 @@ import (
|
|||||||
"go.step.sm/linkedca"
|
"go.step.sm/linkedca"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nodb implements the certificates/Admiclient interface with noops.
|
// nodb implements the certificates/Adminclient interface with noops.
|
||||||
type nodb struct{}
|
type nodb struct{}
|
||||||
|
|
||||||
func newNoDB() *nodb {
|
func newNoDB() *nodb {
|
||||||
@@ -179,7 +179,7 @@ func (client *caConfigClient) loadProvisioner(opts ...ca.ProvisionerOption) (pro
|
|||||||
return nil, errors.New("provisioner options must define either ID or Name to remove")
|
return nil, errors.New("provisioner options must define either ID or Name to remove")
|
||||||
}
|
}
|
||||||
|
|
||||||
return prov, errors.Wrapf(err, "erorr loading provisioner")
|
return prov, errors.Wrapf(err, "error loading provisioner")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *caConfigClient) GetProvisioners(opts ...ca.ProvisionerOption) (provisioner.List, error) {
|
func (client *caConfigClient) GetProvisioners(opts ...ca.ProvisionerOption) (provisioner.List, error) {
|
||||||
|
@@ -578,7 +578,7 @@ Use the '--remove-domain' flag multiple times to remove multiple domains.`,
|
|||||||
}
|
}
|
||||||
oidcGroupFlag = cli.StringSliceFlag{
|
oidcGroupFlag = cli.StringSliceFlag{
|
||||||
Name: "group",
|
Name: "group",
|
||||||
Usage: `The <group> list used to validate the groups extenstion in an OpenID Connect token.
|
Usage: `The <group> list used to validate the groups extension in an OpenID Connect token.
|
||||||
Use the '--group' flag multiple times to configure multiple groups.`,
|
Use the '--group' flag multiple times to configure multiple groups.`,
|
||||||
}
|
}
|
||||||
oidcTenantIDFlag = cli.StringFlag{
|
oidcTenantIDFlag = cli.StringFlag{
|
||||||
|
@@ -165,7 +165,7 @@ flag.`,
|
|||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "pid-file",
|
Name: "pid-file",
|
||||||
Usage: `The <file> from which to read the process id that will be signaled after the certificate
|
Usage: `The <file> from which to read the process id that will be signaled after the certificate
|
||||||
has been rekeyed. By default the the SIGHUP (1) signal will be used, but this can be configured with the **--signal**
|
has been rekeyed. By default the SIGHUP (1) signal will be used, but this can be configured with the **--signal**
|
||||||
flag.`,
|
flag.`,
|
||||||
},
|
},
|
||||||
cli.IntFlag{
|
cli.IntFlag{
|
||||||
|
@@ -177,7 +177,7 @@ flag.`,
|
|||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "pid-file",
|
Name: "pid-file",
|
||||||
Usage: `The <file> from which to read the process id that will be signaled after the certificate
|
Usage: `The <file> from which to read the process id that will be signaled after the certificate
|
||||||
has been renewed. By default the the SIGHUP (1) signal will be used, but this can be configured with the **--signal**
|
has been renewed. By default the SIGHUP (1) signal will be used, but this can be configured with the **--signal**
|
||||||
flag.`,
|
flag.`,
|
||||||
},
|
},
|
||||||
cli.IntFlag{
|
cli.IntFlag{
|
||||||
|
@@ -126,7 +126,7 @@ $ step ca revoke --offline 308893286343609293989051180431574390766
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
Revoke a certificate in offline mode using --cert and --key (the cert/key pair
|
Revoke a certificate in offline mode using --cert and --key (the cert/key pair
|
||||||
will be validated against the root and intermediate certifcates configured in
|
will be validated against the root and intermediate certificates configured in
|
||||||
the step CA):
|
the step CA):
|
||||||
'''
|
'''
|
||||||
$ step ca revoke --offline --cert foo.crt --key foo.key
|
$ step ca revoke --offline --cert foo.crt --key foo.key
|
||||||
|
@@ -16,7 +16,7 @@ import (
|
|||||||
"go.step.sm/crypto/pemutil"
|
"go.step.sm/crypto/pemutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func rootComand() cli.Command {
|
func rootCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Action: command.ActionFunc(rootAction),
|
Action: command.ActionFunc(rootAction),
|
||||||
|
@@ -28,7 +28,7 @@ func bundleCommand() cli.Command {
|
|||||||
: The path to a leaf certificate to bundle with issuing certificate(s).
|
: The path to a leaf certificate to bundle with issuing certificate(s).
|
||||||
|
|
||||||
<ca>
|
<ca>
|
||||||
: The path to the Certificate Authority issusing certificate.
|
: The path to the Certificate Authority issuing certificate.
|
||||||
|
|
||||||
<bundle-file>
|
<bundle-file>
|
||||||
: The path to write the bundle.
|
: The path to write the bundle.
|
||||||
|
@@ -43,17 +43,17 @@ Install a certificate in all the supported truststores:
|
|||||||
$ step certificate install --all root-ca.pem
|
$ step certificate install --all root-ca.pem
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Install a certificate in Firefox and the system trustore:
|
Install a certificate in Firefox and the system truststore:
|
||||||
'''
|
'''
|
||||||
$ step certificate install --firefox root--ca.pem
|
$ step certificate install --firefox root--ca.pem
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Install a certificate in Java and the system trustore:
|
Install a certificate in Java and the system truststore:
|
||||||
'''
|
'''
|
||||||
$ step certificate install --java root-ca.pem
|
$ step certificate install --java root-ca.pem
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Install a certificate in Firefox, Java, but not in the system trustore:
|
Install a certificate in Firefox, Java, but not in the system truststore:
|
||||||
'''
|
'''
|
||||||
$ step certificate install --firefox --java --no-system root-ca.pem
|
$ step certificate install --firefox --java --no-system root-ca.pem
|
||||||
'''`,
|
'''`,
|
||||||
@@ -113,12 +113,12 @@ Uninstall a certificate from all the supported truststores:
|
|||||||
$ step certificate uninstall --all root-ca.pem
|
$ step certificate uninstall --all root-ca.pem
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Uninstall a certificate from Firefox and the system trustore:
|
Uninstall a certificate from Firefox and the system truststore:
|
||||||
'''
|
'''
|
||||||
$ step certificate uninstall --firefox root--ca.pem
|
$ step certificate uninstall --firefox root--ca.pem
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Uninstall a certificate infrom Java and the system trustore:
|
Uninstall a certificate from Java and the system truststore:
|
||||||
'''
|
'''
|
||||||
$ step certificate uninstall --java root-ca.pem
|
$ step certificate uninstall --java root-ca.pem
|
||||||
'''
|
'''
|
||||||
|
@@ -147,7 +147,7 @@ func p12Action(ctx *cli.Context) error {
|
|||||||
|
|
||||||
// The first certificate in the bundle will be our server cert
|
// The first certificate in the bundle will be our server cert
|
||||||
x509Cert := x509CertBundle[0]
|
x509Cert := x509CertBundle[0]
|
||||||
// Any remaning certs will be intermediates for the server
|
// Any remaining certs will be intermediates for the server
|
||||||
x509CAs = append(x509CAs, x509CertBundle[1:]...)
|
x509CAs = append(x509CAs, x509CertBundle[1:]...)
|
||||||
|
|
||||||
pkcs12Data, err = pkcs12.Encode(rand.Reader, key, x509Cert, x509CAs, password)
|
pkcs12Data, err = pkcs12.Encode(rand.Reader, key, x509Cert, x509CAs, password)
|
||||||
|
@@ -71,7 +71,7 @@ func getPeerCertificates(addr, serverName, roots string, insecure bool) ([]*x509
|
|||||||
// by the URL prefix is used.
|
// by the URL prefix is used.
|
||||||
//
|
//
|
||||||
// Examples:
|
// Examples:
|
||||||
// trimURL("https://smallstep.com/onbaording") -> "smallstep.com:443", true, nil
|
// trimURL("https://smallstep.com/onboarding") -> "smallstep.com:443", true, nil
|
||||||
// trimURL("https://ca.smallSTEP.com:8080") -> "ca.smallSTEP.com:8080", true, nil
|
// trimURL("https://ca.smallSTEP.com:8080") -> "ca.smallSTEP.com:8080", true, nil
|
||||||
// trimURL("./certs/root_ca.crt") -> "", false, nil
|
// trimURL("./certs/root_ca.crt") -> "", false, nil
|
||||||
// trimURL("hTtPs://sMaLlStEp.cOm") -> "sMaLlStEp.cOm:443", true, nil
|
// trimURL("hTtPs://sMaLlStEp.cOm") -> "sMaLlStEp.cOm:443", true, nil
|
||||||
|
@@ -266,7 +266,7 @@ func inspectAction(ctx *cli.Context) error {
|
|||||||
type CRL struct {
|
type CRL struct {
|
||||||
Version int `json:"version"`
|
Version int `json:"version"`
|
||||||
SignatureAlgorithm SignatureAlgorithm `json:"signature_algorithm"`
|
SignatureAlgorithm SignatureAlgorithm `json:"signature_algorithm"`
|
||||||
Issuer DistinguisedName `json:"issuer"`
|
Issuer DistinguishedName `json:"issuer"`
|
||||||
ThisUpdate time.Time `json:"this_update"`
|
ThisUpdate time.Time `json:"this_update"`
|
||||||
NextUpdate time.Time `json:"next_update"`
|
NextUpdate time.Time `json:"next_update"`
|
||||||
RevokedCertificates []RevokedCertificate `json:"revoked_certificates"`
|
RevokedCertificates []RevokedCertificate `json:"revoked_certificates"`
|
||||||
@@ -417,8 +417,8 @@ type Signature struct {
|
|||||||
Reason string `json:"reason,omitempty"`
|
Reason string `json:"reason,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DistinguisedName is the JSON representation of the CRL issuer.
|
// DistinguishedName is the JSON representation of the CRL issuer.
|
||||||
type DistinguisedName struct {
|
type DistinguishedName struct {
|
||||||
Country []string `json:"country,omitempty"`
|
Country []string `json:"country,omitempty"`
|
||||||
Organization []string `json:"organization,omitempty"`
|
Organization []string `json:"organization,omitempty"`
|
||||||
OrganizationalUnit []string `json:"organizational_unit,omitempty"`
|
OrganizationalUnit []string `json:"organizational_unit,omitempty"`
|
||||||
@@ -433,7 +433,7 @@ type DistinguisedName struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns the one line representation of the distinguished name.
|
// String returns the one line representation of the distinguished name.
|
||||||
func (d DistinguisedName) String() string {
|
func (d DistinguishedName) String() string {
|
||||||
var parts []string
|
var parts []string
|
||||||
for _, dn := range d.raw {
|
for _, dn := range d.raw {
|
||||||
v := strings.ReplaceAll(pkix.RDNSequence{dn}.String(), "\\,", ",")
|
v := strings.ReplaceAll(pkix.RDNSequence{dn}.String(), "\\,", ",")
|
||||||
@@ -442,7 +442,7 @@ func (d DistinguisedName) String() string {
|
|||||||
return strings.Join(parts, " ")
|
return strings.Join(parts, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDistinguishedName(seq pkix.RDNSequence) DistinguisedName {
|
func newDistinguishedName(seq pkix.RDNSequence) DistinguishedName {
|
||||||
var n pkix.Name
|
var n pkix.Name
|
||||||
n.FillFromRDNSequence(&seq)
|
n.FillFromRDNSequence(&seq)
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ func newDistinguishedName(seq pkix.RDNSequence) DistinguisedName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DistinguisedName{
|
return DistinguishedName{
|
||||||
Country: n.Country,
|
Country: n.Country,
|
||||||
Organization: n.Organization,
|
Organization: n.Organization,
|
||||||
OrganizationalUnit: n.OrganizationalUnit,
|
OrganizationalUnit: n.OrganizationalUnit,
|
||||||
|
@@ -74,7 +74,7 @@ risks. That said, many of these factors are beyond the scope of this tool.
|
|||||||
compared to RSA. The strength of these keys is generally considered sufficient
|
compared to RSA. The strength of these keys is generally considered sufficient
|
||||||
for the predictable and foreseeable future.
|
for the predictable and foreseeable future.
|
||||||
|
|
||||||
: Note that for cryptographic protocols that have perfect forward secrecry and
|
: Note that for cryptographic protocols that have perfect forward secrecy and
|
||||||
only use asymmetric keys for symmetric key negotiation your system will remain
|
only use asymmetric keys for symmetric key negotiation your system will remain
|
||||||
secure against future threats as long as the keys are large enough that they
|
secure against future threats as long as the keys are large enough that they
|
||||||
cannot be cracked today. In other words, sizing your keys to protect against
|
cannot be cracked today. In other words, sizing your keys to protect against
|
||||||
@@ -111,7 +111,7 @@ risks. That said, many of these factors are beyond the scope of this tool.
|
|||||||
opted not to gate non-safe curves**. We've further elected to make **P-256**
|
opted not to gate non-safe curves**. We've further elected to make **P-256**
|
||||||
the default curve for EC keys.
|
the default curve for EC keys.
|
||||||
|
|
||||||
: Still, it is important to be aware of the security risks assocated with their
|
: Still, it is important to be aware of the security risks associated with their
|
||||||
risk. You should consider using "safe curves" if possible. We may change our
|
risk. You should consider using "safe curves" if possible. We may change our
|
||||||
mind as support for safe curves improves.
|
mind as support for safe curves improves.
|
||||||
|
|
||||||
|
@@ -72,13 +72,13 @@ options must match unless the **--subtle** flag is also passed.
|
|||||||
: ECDH-ES using Concat KDF and CEK wrapped with "A256KW
|
: ECDH-ES using Concat KDF and CEK wrapped with "A256KW
|
||||||
|
|
||||||
**A128GCMKW**
|
**A128GCMKW**
|
||||||
: Key wrappiung with AES GCM using 128-bit key
|
: Key wrapping with AES GCM using 128-bit key
|
||||||
|
|
||||||
**A192GCMKW**
|
**A192GCMKW**
|
||||||
: Key wrappiung with AES GCM using 192-bit key
|
: Key wrapping with AES GCM using 192-bit key
|
||||||
|
|
||||||
**A256GCMKW** (default for oct keys)
|
**A256GCMKW** (default for oct keys)
|
||||||
: Key wrappiung with AES GCM using 256-bit key
|
: Key wrapping with AES GCM using 256-bit key
|
||||||
|
|
||||||
**PBES2-HS256+A128KW**
|
**PBES2-HS256+A128KW**
|
||||||
: PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
: PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
||||||
|
@@ -39,7 +39,7 @@ parts:
|
|||||||
* Ciphertext: the ciphertext value resulting produced from authenticated
|
* Ciphertext: the ciphertext value resulting produced from authenticated
|
||||||
encryption of the plaintext with additional authenticated data
|
encryption of the plaintext with additional authenticated data
|
||||||
|
|
||||||
* Authentication Tag: value resulting fromthe authenticated encryption of
|
* Authentication Tag: value resulting from the authenticated encryption of
|
||||||
the plaintext with additional authenticated data
|
the plaintext with additional authenticated data
|
||||||
|
|
||||||
## What's with encrypted key?
|
## What's with encrypted key?
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
// 128-bit salt
|
// 128-bit salt
|
||||||
pbkdf2SaltSize = 16
|
pbkdf2SaltSize = 16
|
||||||
// 100k iterations. Nist recommends at least 10k, 1Passsword uses 100k.
|
// 100k iterations. Nist recommends at least 10k, 1Password uses 100k.
|
||||||
pbkdf2Iterations = 100000
|
pbkdf2Iterations = 100000
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ All flags are optional. Defaults are suitable for most use cases.
|
|||||||
## POSITIONAL ARGUMENTS
|
## POSITIONAL ARGUMENTS
|
||||||
|
|
||||||
<public-jwk-file>
|
<public-jwk-file>
|
||||||
: Path to which the the public JWK should be written
|
: Path to which the public JWK should be written
|
||||||
|
|
||||||
<private-jwk-file>
|
<private-jwk-file>
|
||||||
: Path to which the (JWE encrypted) private JWK should be written
|
: Path to which the (JWE encrypted) private JWK should be written
|
||||||
|
@@ -19,7 +19,7 @@ JWK Set is a JSON object with a "keys" member whose value is an array of JWKs.
|
|||||||
Cryptographic algorithms and identifiers for used by JWKs are defined by the
|
Cryptographic algorithms and identifiers for used by JWKs are defined by the
|
||||||
JSON Web Algorithms (JWA) specification in RFC7518. This tool also supports
|
JSON Web Algorithms (JWA) specification in RFC7518. This tool also supports
|
||||||
extensions defined in standards track RFC8037 defining curve and algorithm
|
extensions defined in standards track RFC8037 defining curve and algorithm
|
||||||
identifiers for Edwards-curve Digial Signatures.
|
identifiers for Edwards-curve Digital Signatures.
|
||||||
|
|
||||||
JWKs and JWK Sets are used in the JSON Web Signature (JWS; RFC7515) and JSON
|
JWKs and JWK Sets are used in the JSON Web Signature (JWS; RFC7515) and JSON
|
||||||
Web Encryption (JWE; RFC7516) specifications for signing and encrypting JSON
|
Web Encryption (JWE; RFC7516) specifications for signing and encrypting JSON
|
||||||
|
@@ -55,7 +55,7 @@ eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tIiwiZXhwIjoxNTM1MjQyNDcyLCJpYXQiOjE1MzI1NjQw
|
|||||||
DlSkxICjk2h1LarwJgXPbXQe7DwpLMOCvWp3I4GMcBP_5_QYPhVNBPQEeTKAUuQjYwlxZ5zVQnyp8ujvyf1Lqw
|
DlSkxICjk2h1LarwJgXPbXQe7DwpLMOCvWp3I4GMcBP_5_QYPhVNBPQEeTKAUuQjYwlxZ5zVQnyp8ujvyf1Lqw
|
||||||
'''
|
'''
|
||||||
|
|
||||||
Verify the the previous token:
|
Verify the previous token:
|
||||||
'''
|
'''
|
||||||
$ echo $TOKEN | step crypto jwt verify --key p256.pub.json --iss "joe@example.com" --aud "https://example.com"
|
$ echo $TOKEN | step crypto jwt verify --key p256.pub.json --iss "joe@example.com" --aud "https://example.com"
|
||||||
{
|
{
|
||||||
|
@@ -146,7 +146,7 @@ func verifyAction(ctx *cli.Context) error {
|
|||||||
kid = tok.Headers[0].KeyID
|
kid = tok.Headers[0].KeyID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate subtled
|
// Validate subtle
|
||||||
isSubtle := ctx.Bool("subtle")
|
isSubtle := ctx.Bool("subtle")
|
||||||
iss := ctx.String("iss")
|
iss := ctx.String("iss")
|
||||||
aud := ctx.String("aud")
|
aud := ctx.String("aud")
|
||||||
@@ -263,7 +263,7 @@ func validateClaimsWithLeeway(ctx *cli.Context, c jose.Claims, e jose.Expected,
|
|||||||
|
|
||||||
// we're not currently checking the subject
|
// we're not currently checking the subject
|
||||||
if e.Subject != "" && e.Subject != c.Subject {
|
if e.Subject != "" && e.Subject != c.Subject {
|
||||||
ers = append(ers, "invalid subject subject (sub)")
|
ers = append(ers, "invalid subject (sub)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're not currently checking the id
|
// we're not currently checking the id
|
||||||
|
@@ -325,7 +325,7 @@ func parseJWK(ctx *cli.Context, b []byte) (interface{}, error) {
|
|||||||
// Parse decrypted key
|
// Parse decrypted key
|
||||||
var jwk jose.JSONWebKey
|
var jwk jose.JSONWebKey
|
||||||
if err := json.Unmarshal(b, &jwk); err != nil {
|
if err := json.Unmarshal(b, &jwk); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshalling key")
|
return nil, errors.Wrap(err, "error unmarshaling key")
|
||||||
}
|
}
|
||||||
if jwk.Key == nil {
|
if jwk.Key == nil {
|
||||||
return nil, errors.New("error parsing key: not found")
|
return nil, errors.New("error parsing key: not found")
|
||||||
|
@@ -286,7 +286,7 @@ func boxOpenAction(ctx *cli.Context) error {
|
|||||||
copy(pb[:], pub)
|
copy(pb[:], pub)
|
||||||
copy(pv[:], priv)
|
copy(pv[:], priv)
|
||||||
|
|
||||||
// Fixme: if we prepend the nonce in the seal we can use use rawInput[24:]
|
// Fixme: if we prepend the nonce in the seal we can use rawInput[24:]
|
||||||
// as the message and rawInput[:24] as the nonce instead of requiring one.
|
// as the message and rawInput[:24] as the nonce instead of requiring one.
|
||||||
raw, ok := box.Open(nil, rawInput, &n, &pb, &pv)
|
raw, ok := box.Open(nil, rawInput, &n, &pb, &pv)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@@ -188,7 +188,7 @@ func secretboxOpenAction(ctx *cli.Context) error {
|
|||||||
copy(n[:], nonce)
|
copy(n[:], nonce)
|
||||||
copy(k[:], key)
|
copy(k[:], key)
|
||||||
|
|
||||||
// Fixme: if we prepend the nonce in the seal we can use use rawInput[24:]
|
// Fixme: if we prepend the nonce in the seal we can use rawInput[24:]
|
||||||
// as the message and rawInput[:24] as the nonce instead of requiring one.
|
// as the message and rawInput[:24] as the nonce instead of requiring one.
|
||||||
raw, ok := secretbox.Open(nil, rawInput, &n, &k)
|
raw, ok := secretbox.Open(nil, rawInput, &n, &k)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@@ -857,7 +857,7 @@ func (o *oauth) DoDeviceAuthorization() (*token, error) {
|
|||||||
|
|
||||||
var idr identifyDeviceResponse
|
var idr identifyDeviceResponse
|
||||||
if err := json.NewDecoder(bytes.NewReader(b)).Decode(&idr); err != nil {
|
if err := json.NewDecoder(bytes.NewReader(b)).Decode(&idr); err != nil {
|
||||||
return nil, errors.Wrap(err, "failure decoding device authz response to JWON")
|
return nil, errors.Wrap(err, "failure decoding device authz response to JSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
@@ -33,7 +33,7 @@ func certificateCommand() cli.Command {
|
|||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "certificate",
|
Name: "certificate",
|
||||||
Action: command.ActionFunc(certificateAction),
|
Action: command.ActionFunc(certificateAction),
|
||||||
Usage: "sign a SSH certificate using the the SSH CA",
|
Usage: "sign a SSH certificate using the SSH CA",
|
||||||
UsageText: `**step ssh certificate** <key-id> <key-file>
|
UsageText: `**step ssh certificate** <key-id> <key-file>
|
||||||
[**--host**] [--**host-id**] [**--sign**] [**--principal**=<string>]
|
[**--host**] [--**host-id**] [**--sign**] [**--principal**=<string>]
|
||||||
[**--password-file**=<file>] [**--provisioner-password-file**=<file>]
|
[**--password-file**=<file>] [**--provisioner-password-file**=<file>]
|
||||||
|
@@ -30,7 +30,7 @@ func rekeyCommand() cli.Command {
|
|||||||
[**--offline**] [**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[**--offline**] [**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
[**--context**=<name>]`,
|
[**--context**=<name>]`,
|
||||||
Description: `**step ssh rekey** command generates a new SSH Certificate and key using
|
Description: `**step ssh rekey** command generates a new SSH Certificate and key using
|
||||||
an existing SSH Cerfificate and key pair to authenticate and templatize the
|
an existing SSH Certificate and key pair to authenticate and templatize the
|
||||||
request. It writes the new certificate to disk - either overwriting
|
request. It writes the new certificate to disk - either overwriting
|
||||||
<ssh-cert> or using new files when the **--out**=<file> flag is used.
|
<ssh-cert> or using new files when the **--out**=<file> flag is used.
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ func renewCommand() cli.Command {
|
|||||||
[**--issuer**=<name>] [**--password-file**=<file>] [**--force**] [**--offline**]
|
[**--issuer**=<name>] [**--password-file**=<file>] [**--force**] [**--offline**]
|
||||||
[**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
[**--context**=<name>]`,
|
[**--context**=<name>]`,
|
||||||
Description: `**step ssh renew** command renews an SSH Host Cerfificate
|
Description: `**step ssh renew** command renews an SSH Host Certificate
|
||||||
using [step certificates](https://github.com/smallstep/certificates).
|
using [step certificates](https://github.com/smallstep/certificates).
|
||||||
It writes the new certificate to disk - either overwriting <ssh-cert> or
|
It writes the new certificate to disk - either overwriting <ssh-cert> or
|
||||||
using a new file when the **--out**=<file> flag is used. This command cannot
|
using a new file when the **--out**=<file> flag is used. This command cannot
|
||||||
|
@@ -30,7 +30,7 @@ func revokeCommand() cli.Command {
|
|||||||
[**--offline**] [**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
[**--offline**] [**--ca-config**=<file>] [**--ca-url**=<uri>] [**--root**=<file>]
|
||||||
[**--context**=<name>]`,
|
[**--context**=<name>]`,
|
||||||
|
|
||||||
Description: `**step ssh revoke** command revokes an SSH Cerfificate
|
Description: `**step ssh revoke** command revokes an SSH Certificate
|
||||||
using [step certificates](https://github.com/smallstep/certificates).
|
using [step certificates](https://github.com/smallstep/certificates).
|
||||||
|
|
||||||
## POSITIONAL ARGUMENTS
|
## POSITIONAL ARGUMENTS
|
||||||
|
@@ -467,7 +467,7 @@ func ParseTimeDuration(ctx *cli.Context) (notBefore, notAfter api.TimeDuration,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseTemplateData parses the set and and set-file flags and returns a json
|
// ParseTemplateData parses the set and set-file flags and returns a json
|
||||||
// message to be used in certificate templates.
|
// message to be used in certificate templates.
|
||||||
func ParseTemplateData(ctx *cli.Context) (json.RawMessage, error) {
|
func ParseTemplateData(ctx *cli.Context) (json.RawMessage, error) {
|
||||||
data, err := GetTemplateData(ctx)
|
data, err := GetTemplateData(ctx)
|
||||||
|
@@ -54,7 +54,7 @@ func WithStdin(command string, r io.Reader) ([]byte, error) {
|
|||||||
return cmd.Output()
|
return cmd.Output()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLICommand repreents a command-line command to execute.
|
// CLICommand represents a command-line command to execute.
|
||||||
type CLICommand struct {
|
type CLICommand struct {
|
||||||
command string
|
command string
|
||||||
arguments string
|
arguments string
|
||||||
|
@@ -236,7 +236,7 @@ func (j JWKTest) checkPubPriv(t *testing.T, m map[string]interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
k, ok := m["k"]
|
k, ok := m["k"]
|
||||||
assert.True(t, ok, "JWK with \"kty\" of \"oct\" should have \"k\" paramater (key)")
|
assert.True(t, ok, "JWK with \"kty\" of \"oct\" should have \"k\" parameter (key)")
|
||||||
|
|
||||||
// Check `k` is correct size
|
// Check `k` is correct size
|
||||||
checkSizeBytes(k.(string), 32)
|
checkSizeBytes(k.(string), 32)
|
||||||
|
@@ -110,7 +110,7 @@ func (j JWTSignTest) test(t *testing.T, name string) string {
|
|||||||
var jwt string
|
var jwt string
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
// Beware. This is fragile as hell. Ugh. If the output or prompt for the
|
// Beware. This is fragile as hell. Ugh. If the output or prompt for the
|
||||||
// jwt sign cubcommand changes this will need to change too.
|
// jwt sign subcommand changes this will need to change too.
|
||||||
if j.jwk.password != "" {
|
if j.jwk.password != "" {
|
||||||
cmd, err := gexpect.Spawn(j.command.cmd())
|
cmd, err := gexpect.Spawn(j.command.cmd())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
@@ -694,7 +694,7 @@ func TestCryptoJWT(t *testing.T) {
|
|||||||
jwt = mkossljwt(t, `{"typ": "JWT", "alg": "RS384"}`, `{"iss": "foo", "sub": "bar"}`, fmt.Sprintf("<(echo -en %q)", pem))
|
jwt = mkossljwt(t, `{"typ": "JWT", "alg": "RS384"}`, `{"iss": "foo", "sub": "bar"}`, fmt.Sprintf("<(echo -en %q)", pem))
|
||||||
tst.verify.setFlag("iss", "foo").setFlag("aud", "bar").setFlag("alg", "RS384").fail(t, "wrong-alg", jwt, "alg RS384 does not match the alg on testdata-tmp/jwt-jwk-RSA-pub.json\n")
|
tst.verify.setFlag("iss", "foo").setFlag("aud", "bar").setFlag("alg", "RS384").fail(t, "wrong-alg", jwt, "alg RS384 does not match the alg on testdata-tmp/jwt-jwk-RSA-pub.json\n")
|
||||||
|
|
||||||
// We don't currently support JSON Serialization, Flattened JSON Serialzation, or multiple signatures
|
// We don't currently support JSON Serialization, Flattened JSON Serialization, or multiple signatures
|
||||||
// TODO: Right now these are parse failures. They should probably parse correctly and give more helpful error messages.
|
// TODO: Right now these are parse failures. They should probably parse correctly and give more helpful error messages.
|
||||||
vtst := NewJWTVerifyTest(JWK{"testdata/rsa2048.pub", "testdata/rsa2048.pem", "", true, false}).setFlag("iss", "foo").setFlag("aud", "bar").setFlag("alg", "RS256")
|
vtst := NewJWTVerifyTest(JWK{"testdata/rsa2048.pub", "testdata/rsa2048.pem", "", true, false}).setFlag("iss", "foo").setFlag("aud", "bar").setFlag("alg", "RS256")
|
||||||
jwtb, _ := os.ReadFile("testdata/jwt-json-serialization.json")
|
jwtb, _ := os.ReadFile("testdata/jwt-json-serialization.json")
|
||||||
@@ -713,7 +713,7 @@ func TestCryptoJWT(t *testing.T) {
|
|||||||
t.Run("nbf", func(t *testing.T) {
|
t.Run("nbf", func(t *testing.T) {
|
||||||
tst := mkjwt(jwkec)
|
tst := mkjwt(jwkec)
|
||||||
jwt := tst.nbf(extraTime).sign.test(t, "sign")
|
jwt := tst.nbf(extraTime).sign.test(t, "sign")
|
||||||
tst.verify.fail(t, "verify-tosoon", jwt, "validation failed: token not valid yet (nbf)\n")
|
tst.verify.fail(t, "verify-too-soon", jwt, "validation failed: token not valid yet (nbf)\n")
|
||||||
time.Sleep(extraTime)
|
time.Sleep(extraTime)
|
||||||
tst.verify.test(t, "verify-succeed", jwt)
|
tst.verify.test(t, "verify-succeed", jwt)
|
||||||
if t.Failed() {
|
if t.Failed() {
|
||||||
|
@@ -16,7 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ScryptMaxCost the the maximum value for ln. Maximum is set to avoid
|
// ScryptMaxCost the maximum value for ln. Maximum is set to avoid
|
||||||
// panics due to not enough memory errors. Memory used is ~4*32*(2^ln)*r
|
// panics due to not enough memory errors. Memory used is ~4*32*(2^ln)*r
|
||||||
// bytes.
|
// bytes.
|
||||||
ScryptMaxCost = 20
|
ScryptMaxCost = 20
|
||||||
|
@@ -139,7 +139,7 @@ func parseDSA(in []byte) (*dsa.PublicKey, error) {
|
|||||||
Rest []byte `ssh:"rest"`
|
Rest []byte `ssh:"rest"`
|
||||||
}
|
}
|
||||||
if err := ssh.Unmarshal(in, &w); err != nil {
|
if err := ssh.Unmarshal(in, &w); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshalling public key")
|
return nil, errors.Wrap(err, "error unmarshaling public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
param := dsa.Parameters{
|
param := dsa.Parameters{
|
||||||
@@ -161,7 +161,7 @@ func parseRSA(in []byte) (*rsa.PublicKey, error) {
|
|||||||
Rest []byte `ssh:"rest"`
|
Rest []byte `ssh:"rest"`
|
||||||
}
|
}
|
||||||
if err := ssh.Unmarshal(in, &w); err != nil {
|
if err := ssh.Unmarshal(in, &w); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshalling public key")
|
return nil, errors.Wrap(err, "error unmarshaling public key")
|
||||||
}
|
}
|
||||||
if w.E.BitLen() > 24 {
|
if w.E.BitLen() > 24 {
|
||||||
return nil, errors.New("invalid public key: exponent too large")
|
return nil, errors.New("invalid public key: exponent too large")
|
||||||
@@ -186,7 +186,7 @@ func parseECDSA(in []byte) (*ecdsa.PublicKey, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := ssh.Unmarshal(in, &w); err != nil {
|
if err := ssh.Unmarshal(in, &w); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshalling public key")
|
return nil, errors.Wrap(err, "error unmarshaling public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
key := new(ecdsa.PublicKey)
|
key := new(ecdsa.PublicKey)
|
||||||
@@ -217,7 +217,7 @@ func parseED25519(in []byte) (ed25519.PublicKey, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := ssh.Unmarshal(in, &w); err != nil {
|
if err := ssh.Unmarshal(in, &w); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshalling public key")
|
return nil, errors.Wrap(err, "error unmarshaling public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ed25519.PublicKey(w.KeyBytes), nil
|
return ed25519.PublicKey(w.KeyBytes), nil
|
||||||
|
@@ -163,7 +163,7 @@ Extensions
|
|||||||
In addition to the standard markdown syntax, this package
|
In addition to the standard markdown syntax, this package
|
||||||
implements the following extensions:
|
implements the following extensions:
|
||||||
|
|
||||||
* **Intra-word emphasis supression**. The `_` character is
|
* **Intra-word emphasis suppression**. The `_` character is
|
||||||
commonly used inside words when discussing code, so having
|
commonly used inside words when discussing code, so having
|
||||||
markdown interpret it as an emphasis command is usually the
|
markdown interpret it as an emphasis command is usually the
|
||||||
wrong thing. Blackfriday lets you treat all emphasis markers as
|
wrong thing. Blackfriday lets you treat all emphasis markers as
|
||||||
@@ -233,7 +233,7 @@ implements the following extensions:
|
|||||||
|
|
||||||
* **Smart fractions**, where anything that looks like a fraction
|
* **Smart fractions**, where anything that looks like a fraction
|
||||||
is translated into suitable HTML (instead of just a few special
|
is translated into suitable HTML (instead of just a few special
|
||||||
cases like most smartypant processors). For example, `4/5`
|
cases like most smartypants processors). For example, `4/5`
|
||||||
becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as
|
becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as
|
||||||
<sup>4</sup>⁄<sub>5</sub>.
|
<sup>4</sup>⁄<sub>5</sub>.
|
||||||
|
|
||||||
|
@@ -733,8 +733,8 @@ func TestOrderedList(t *testing.T) {
|
|||||||
"1. List\n\n code block with spaces\n",
|
"1. List\n\n code block with spaces\n",
|
||||||
"<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
|
"<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
|
||||||
|
|
||||||
"1. List\n * Mixted list\n",
|
"1. List\n * Mixed list\n",
|
||||||
"<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
|
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
||||||
|
|
||||||
"1. List\n * Mixed list\n",
|
"1. List\n * Mixed list\n",
|
||||||
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
||||||
@@ -876,8 +876,8 @@ func TestPreformattedHtml(t *testing.T) {
|
|||||||
"<div>\nAnything here\n </div>\n",
|
"<div>\nAnything here\n </div>\n",
|
||||||
"<div>\nAnything here\n </div>\n",
|
"<div>\nAnything here\n </div>\n",
|
||||||
|
|
||||||
"<div>\nThis is *not* &proceessed\n</div>\n",
|
"<div>\nThis is *not* &processed\n</div>\n",
|
||||||
"<div>\nThis is *not* &proceessed\n</div>\n",
|
"<div>\nThis is *not* &processed\n</div>\n",
|
||||||
|
|
||||||
"<faketag>\n Something\n</faketag>\n",
|
"<faketag>\n Something\n</faketag>\n",
|
||||||
"<p><faketag>\n Something\n</faketag></p>\n",
|
"<p><faketag>\n Something\n</faketag></p>\n",
|
||||||
@@ -1369,8 +1369,8 @@ func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
|
|||||||
"1. List\n\n code block with spaces\n",
|
"1. List\n\n code block with spaces\n",
|
||||||
"<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
|
"<ol>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ol>\n",
|
||||||
|
|
||||||
"1. List\n * Mixted list\n",
|
"1. List\n * Mixed list\n",
|
||||||
"<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
|
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
||||||
|
|
||||||
"1. List\n * Mixed list\n",
|
"1. List\n * Mixed list\n",
|
||||||
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
|
||||||
|
@@ -303,7 +303,7 @@ func needSkipLink(flags HTMLFlags, dest []byte) bool {
|
|||||||
return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)
|
return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSmartypantable(node *Node) bool {
|
func isSmartypantsable(node *Node) bool {
|
||||||
pt := node.Parent.Type
|
pt := node.Parent.Type
|
||||||
return pt != Link && pt != CodeBlock && pt != Code
|
return pt != Link && pt != CodeBlock && pt != Code
|
||||||
}
|
}
|
||||||
|
@@ -469,12 +469,12 @@ func (p *Markdown) parseRefsToAST() {
|
|||||||
// The basic format is:
|
// The basic format is:
|
||||||
//
|
//
|
||||||
// [1]: http://www.google.com/ "Google"
|
// [1]: http://www.google.com/ "Google"
|
||||||
// [2]: http://www.github.com/ "Github"
|
// [2]: http://www.github.com/ "GitHub"
|
||||||
//
|
//
|
||||||
// Anywhere in the document, the reference can be linked by referring to its
|
// Anywhere in the document, the reference can be linked by referring to its
|
||||||
// label, i.e., 1 and 2 in this example, as in:
|
// label, i.e., 1 and 2 in this example, as in:
|
||||||
//
|
//
|
||||||
// This library is hosted on [Github][2], a git hosting site.
|
// This library is hosted on [GitHub][2], a git hosting site.
|
||||||
//
|
//
|
||||||
// Actual footnotes as specified in Pandoc and supported by some other Markdown
|
// Actual footnotes as specified in Pandoc and supported by some other Markdown
|
||||||
// libraries such as php-markdown are also taken care of. They look like this:
|
// libraries such as php-markdown are also taken care of. They look like this:
|
||||||
|
@@ -42,7 +42,7 @@ func TestReference(t *testing.T) {
|
|||||||
"Ordered and unordered lists",
|
"Ordered and unordered lists",
|
||||||
"Strong and em together",
|
"Strong and em together",
|
||||||
"Tabs",
|
"Tabs",
|
||||||
"Tidyness",
|
"Tidiness",
|
||||||
}
|
}
|
||||||
doTestsReference(t, files, 0)
|
doTestsReference(t, files, 0)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ func TestReference_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
|
|||||||
"Ordered and unordered lists",
|
"Ordered and unordered lists",
|
||||||
"Strong and em together",
|
"Strong and em together",
|
||||||
"Tabs",
|
"Tabs",
|
||||||
"Tidyness",
|
"Tidiness",
|
||||||
}
|
}
|
||||||
doTestsReference(t, files, NoEmptyLineBeforeBlock)
|
doTestsReference(t, files, NoEmptyLineBeforeBlock)
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ func BenchmarkReference(b *testing.B) {
|
|||||||
"Ordered and unordered lists",
|
"Ordered and unordered lists",
|
||||||
"Strong and em together",
|
"Strong and em together",
|
||||||
"Tabs",
|
"Tabs",
|
||||||
"Tidyness",
|
"Tidiness",
|
||||||
}
|
}
|
||||||
var tests []string
|
var tests []string
|
||||||
for _, basename := range files {
|
for _, basename := range files {
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p>
|
<p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p>
|
||||||
|
|
||||||
<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>
|
<p>Here's a link with an ampersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>
|
||||||
|
|
||||||
<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
|
<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ This & that.
|
|||||||
|
|
||||||
Here's a [link] [1] with an ampersand in the URL.
|
Here's a [link] [1] with an ampersand in the URL.
|
||||||
|
|
||||||
Here's a link with an amersand in the link text: [AT&T] [2].
|
Here's a link with an ampersand in the link text: [AT&T] [2].
|
||||||
|
|
||||||
Here's an inline [link](/script?foo=1&bar=2).
|
Here's an inline [link](/script?foo=1&bar=2).
|
||||||
|
|
||||||
|
@@ -114,7 +114,7 @@ Or, if you prefer, <strong>use two underscores instead</strong>.<
|
|||||||
|
|
||||||
<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
|
<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
|
||||||
<code>+</code>, and <code>-</code>) as list markers. These three markers are
|
<code>+</code>, and <code>-</code>) as list markers. These three markers are
|
||||||
interchangable; this:</p>
|
interchangeable; this:</p>
|
||||||
|
|
||||||
<pre><code>* Candy.
|
<pre><code>* Candy.
|
||||||
* Gum.
|
* Gum.
|
||||||
@@ -275,7 +275,7 @@ it easy to use Markdown to write about HTML example code:</p>
|
|||||||
<pre><code>I strongly recommend against using any `<blink>` tags.
|
<pre><code>I strongly recommend against using any `<blink>` tags.
|
||||||
|
|
||||||
I wish SmartyPants used named entities like `&mdash;`
|
I wish SmartyPants used named entities like `&mdash;`
|
||||||
instead of decimal-encoded entites like `&#8212;`.
|
instead of decimal-encoded entities like `&#8212;`.
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Output:</p>
|
<p>Output:</p>
|
||||||
@@ -285,7 +285,7 @@ instead of decimal-encoded entites like `&#8212;`.
|
|||||||
|
|
||||||
<p>I wish SmartyPants used named entities like
|
<p>I wish SmartyPants used named entities like
|
||||||
<code>&amp;mdash;</code> instead of decimal-encoded
|
<code>&amp;mdash;</code> instead of decimal-encoded
|
||||||
entites like <code>&amp;#8212;</code>.</p>
|
entities like <code>&amp;#8212;</code>.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>To specify an entire block of pre-formatted code, indent every line of
|
<p>To specify an entire block of pre-formatted code, indent every line of
|
||||||
|
@@ -123,7 +123,7 @@ Output:
|
|||||||
|
|
||||||
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
|
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
|
||||||
`+`, and `-`) as list markers. These three markers are
|
`+`, and `-`) as list markers. These three markers are
|
||||||
interchangable; this:
|
interchangeable; this:
|
||||||
|
|
||||||
* Candy.
|
* Candy.
|
||||||
* Gum.
|
* Gum.
|
||||||
@@ -270,7 +270,7 @@ it easy to use Markdown to write about HTML example code:
|
|||||||
I strongly recommend against using any `<blink>` tags.
|
I strongly recommend against using any `<blink>` tags.
|
||||||
|
|
||||||
I wish SmartyPants used named entities like `—`
|
I wish SmartyPants used named entities like `—`
|
||||||
instead of decimal-encoded entites like `—`.
|
instead of decimal-encoded entities like `—`.
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ Output:
|
|||||||
|
|
||||||
<p>I wish SmartyPants used named entities like
|
<p>I wish SmartyPants used named entities like
|
||||||
<code>&mdash;</code> instead of decimal-encoded
|
<code>&mdash;</code> instead of decimal-encoded
|
||||||
entites like <code>&#8212;</code>.</p>
|
entities like <code>&#8212;</code>.</p>
|
||||||
|
|
||||||
|
|
||||||
To specify an entire block of pre-formatted code, indent every line of
|
To specify an entire block of pre-formatted code, indent every line of
|
||||||
|
@@ -302,7 +302,7 @@ Quote Level from the Text menu.</p>
|
|||||||
|
|
||||||
<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>
|
<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>
|
||||||
|
|
||||||
<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
<p>Unordered lists use asterisks, pluses, and hyphens -- interchangeably
|
||||||
-- as list markers:</p>
|
-- as list markers:</p>
|
||||||
|
|
||||||
<pre><code>* Red
|
<pre><code>* Red
|
||||||
@@ -642,7 +642,7 @@ or tabs for padding, which tends to look better with longer URLs:</p>
|
|||||||
<p>Link definitions are only used for creating links during Markdown
|
<p>Link definitions are only used for creating links during Markdown
|
||||||
processing, and are stripped from your document in the HTML output.</p>
|
processing, and are stripped from your document in the HTML output.</p>
|
||||||
|
|
||||||
<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>
|
<p>Link definition names may consist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>
|
||||||
|
|
||||||
<pre><code>[link text][a]
|
<pre><code>[link text][a]
|
||||||
[link text][A]
|
[link text][A]
|
||||||
|
@@ -298,7 +298,7 @@ Quote Level from the Text menu.
|
|||||||
|
|
||||||
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
||||||
|
|
||||||
Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
Unordered lists use asterisks, pluses, and hyphens -- interchangeably
|
||||||
-- as list markers:
|
-- as list markers:
|
||||||
|
|
||||||
* Red
|
* Red
|
||||||
@@ -608,7 +608,7 @@ or tabs for padding, which tends to look better with longer URLs:
|
|||||||
Link definitions are only used for creating links during Markdown
|
Link definitions are only used for creating links during Markdown
|
||||||
processing, and are stripped from your document in the HTML output.
|
processing, and are stripped from your document in the HTML output.
|
||||||
|
|
||||||
Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
|
Link definition names may consist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
|
||||||
|
|
||||||
[link text][a]
|
[link text][a]
|
||||||
[link text][A]
|
[link text][A]
|
||||||
|
@@ -12,7 +12,7 @@ OnCalendar=*:1/15
|
|||||||
; Always run the timer on time.
|
; Always run the timer on time.
|
||||||
AccuracySec=1us
|
AccuracySec=1us
|
||||||
|
|
||||||
; Add jitter to prevent a "thundering hurd" of simultaneous certificate renewals.
|
; Add jitter to prevent a "thundering herd" of simultaneous certificate renewals.
|
||||||
RandomizedDelaySec=5m
|
RandomizedDelaySec=5m
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@@ -11,7 +11,7 @@ OnCalendar=*:1/15
|
|||||||
; Always run the timer on time.
|
; Always run the timer on time.
|
||||||
AccuracySec=1us
|
AccuracySec=1us
|
||||||
|
|
||||||
; Add jitter to prevent a "thundering hurd" of simultaneous certificate renewals.
|
; Add jitter to prevent a "thundering herd" of simultaneous certificate renewals.
|
||||||
RandomizedDelaySec=5m
|
RandomizedDelaySec=5m
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@@ -166,7 +166,7 @@ func (r *Renderer) RenderNode(w io.Writer, node *md.Node, entering bool) md.Walk
|
|||||||
switch node.Type {
|
switch node.Type {
|
||||||
case md.Paragraph:
|
case md.Paragraph:
|
||||||
// Alternative idea here: call r.RenderNode() with our new buffer as
|
// Alternative idea here: call r.RenderNode() with our new buffer as
|
||||||
// `w`. In the `else` condition here render to the outter buffer and
|
// `w`. In the `else` condition here render to the outer buffer and
|
||||||
// always return md.Terminate. So when we enter a paragraph we start
|
// always return md.Terminate. So when we enter a paragraph we start
|
||||||
// parsing with a new output buffer and capture the output.
|
// parsing with a new output buffer and capture the output.
|
||||||
if entering {
|
if entering {
|
||||||
@@ -322,7 +322,7 @@ func (r *Renderer) RenderNode(w io.Writer, node *md.Node, entering bool) md.Walk
|
|||||||
if entering {
|
if entering {
|
||||||
r.capture(r.out.mode)
|
r.capture(r.out.mode)
|
||||||
} else {
|
} else {
|
||||||
// Markdown doens't have a way to create a table without headers.
|
// Markdown doesn't have a way to create a table without headers.
|
||||||
// We've opted to fix that here by not rendering headers at all if
|
// We've opted to fix that here by not rendering headers at all if
|
||||||
// they're empty.
|
// they're empty.
|
||||||
result := r.finishCapture().Bytes()
|
result := r.finishCapture().Bytes()
|
||||||
|
@@ -344,7 +344,7 @@ func loadJWK(ctx *cli.Context, p *provisioner.JWK, tokAttrs tokenAttrs) (jwk *jo
|
|||||||
|
|
||||||
jwk = new(jose.JSONWebKey)
|
jwk = new(jose.JSONWebKey)
|
||||||
if err := json.Unmarshal(decrypted, jwk); err != nil {
|
if err := json.Unmarshal(decrypted, jwk); err != nil {
|
||||||
return nil, "", errors.Wrap(err, "error unmarshalling provisioning key")
|
return nil, "", errors.Wrap(err, "error unmarshaling provisioning key")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Get private key from given key file
|
// Get private key from given key file
|
||||||
|
Reference in New Issue
Block a user