Giter Club home page Giter Club logo

go-pkcs12's Introduction

SSLMate command line client

sslmate is the command line client for SSLMate, a service for purchasing and managing SSL certificates. SSLMate provides easy-to-use tools for buying, renewing, and revoking certificates, for monitoring the expiration date of your certificates, and for synchronizing your certificates between your servers.

SSLMate emphasizes speed, ease-of-use, and automation. For example, the command to purchase a certificate (sslmate buy) typically completes in under a minute and automates the steps of generating a private key, generating a CSR, and building a certificate bundle. SSLMate can automatically renew your certificates, and you can run sslmate download from a cron job so that renewed certificates are automatically downloaded to your server.

To use the sslmate command, you must create a free account at https://sslmate.com.

Dependencies

SSLMate officially supports:

  • Debian 9 and newer
  • Ubuntu 18.04 and newer
  • RHEL/CentOS 7 and 8
  • Amazon Linux 1 and 2
  • Fedora 27 and newer

Packages (.deb, .rpm) for the above operating systems are available.

SSLMate can run on other Unix-based operating systems provided the following software is installed:

  • Perl v5.10.0 or newer.

  • The following Perl modules, which can be installed by running cpan MODULENAME or by installing the corresponding distro package.

    Module Name               Debian/Ubuntu Package       RHEL/CentOS Package
    -----------------------------------------------------------------------------
    URI                       liburi-perl                 perl-URI
    Term::ReadKey             libterm-readkey-perl        perl-TermReadKey
    JSON::PP [1]              libjson-perl                perl-JSON
    LWP (>= 6) [2]            libwww-perl                 perl-libwww-perl
    LWP::Protocol::https [2]  liblwp-protocol-https-perl  perl-LWP-Protocol-https
    

Notes:

  1. JSON::PP is included with Perl 5.14 and later.
  2. LWP is optional; if not available SSLMate will fall back to executing the curl command directly.

Installation

Run make and make install.

The following Makefile variables can be passed on the command line to make and make install:

  • PREFIX=/path - Install to given path (default: /usr/local)
  • DESTDIR=/path - Stage installed files under the given path instead of installing directly to the filesystem (intended for package building)

Example:

make PREFIX=/usr
make install PREFIX=/usr DESTDIR=/tmp/pkgroot

Getting started

See SSLMate's guide to getting started.

Getting help

go-pkcs12's People

Contributors

0intro avatar aclements avatar adg avatar agl avatar agwa avatar alexbrainman avatar bifurcation avatar bradfitz avatar cixtor avatar cmars avatar coruus avatar davecheney avatar dchest avatar dmitris avatar doug-fitzmaurice-rowden avatar dsymonds avatar ebfe avatar hanwen avatar ianlancetaylor avatar joekyo avatar jonathanpittman avatar kardianos avatar kevinburke avatar kreichgauer avatar marete avatar minux avatar mundaym avatar rsc avatar taralx avatar tklauser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-pkcs12's Issues

pkcs12: expected exactly one certificate in the certBag

go newbie here, got some confusion.

func main() {
	keyBytes, err := rsa.GenerateKey(rand.Reader, 1024)

	if err != nil {
		panic(err)
	}

	if err := keyBytes.Validate(); err != nil {
		panic(err)
	}

	dn := pkix.Name{
		Country:            []string{"EN"},
		Organization:       []string{"org"},
		OrganizationalUnit: []string{"org"},
		Locality:           []string{"city"},
		Province:           []string{"province"},
		CommonName:         "name",
	}

	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)

	template := x509.Certificate{
		Subject:            dn,
		SignatureAlgorithm: x509.SHA256WithRSA,
		SerialNumber:       serialNumber,
	}
	pfxBytes, err := pkcs12.Encode(rand.Reader, keyBytes, &template, []*x509.Certificate{}, pkcs12.DefaultPassword)

	if err != nil {
		panic(err)
	}

	_, _, err = pkcs12.Decode(pfxBytes, pkcs12.DefaultPassword)
	if err != nil {
		panic(err)  // I got: pkcs12: expected exactly one certificate in the certBag
	}
}

Did I make any mistake with the pkcs12.Encode or others? Many thanks

test error

Hi, i have to test this package before using, there is a problem.
go test software.sslmate.com/src/go-pkcs12 failed with status 2
src/software.sslmate.com/src/go-pkcs12/pkcs12_test.go:135:21: rsaPk.PublicKey.Equal undefined (type rsa.PublicKey has no field or method Equal)

Use error wrapping when relevant

Hello. I am currently writing some tests for our application, and I have specifically hit the issue that pkcs12.DecodeChain can return an error that is not easy to check for, due wrapping other errors with errors.New():

return nil, nil, errors.New("pkcs12: error reading P12 data: " + err.Error())

If the returned error here (and other locations where a dynamic error message can be returned) uses fmt.Errorf to wrap the error, I would be able to use errors.Is to check it, using code such as:

cert, pass := generateCert() // helper function

_, _, _, err := pkcs12.DecodeChain(cert, pass)
if !errors.Is(err, errors.New("pkcs12: error reading P12 data:") {
    t.Errorf("expected error %v, got %v", testcase.expectedError, err)
}

Right now I have to do some annoying string prefix equality check, which is brittle and prone to error..

What I suggest is to convert errors.New("pkcs12: error reading P12 data: " + err.Error()) to fmt.Errorf("pkcs12: error reading P12 data: %w", err.Error()).
This conversion should be done anywhere else, like:

return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error())

return nil, errors.New("pkcs12: error decrypting PKCS#8 shrouded key bag: " + err.Error())

return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error())

return nil, errors.New("pkcs12: error parsing PKCS#8 private key: " + err.Error())

etc.

Predefined error value for unexpected number of safe bags

I have been working on a project where this error is significant

err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU")

Can we create a predefined error value for this?. It makes it easy for error value comparison. I suggest something like this

var ErrExpectedTwoSafeBags error = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU")

So We can do something like this

pfx, cert, err := pkcs12.Decode(pfxData, password)
if errors.Is(err,pkcs12.ErrExpectedTwoSafeBags){
    // LoadChain
}

instead of

if err.Error() == "pkcs12: expected exactly two safe bags in the PFX PDU" {
}

Having an issue onverting PFX to Pem

I'm trying to convert PFX to PEM without success due to this error:

pkcs12: error reading P12 data: asn1: syntax error: indefinite length found (not DER)

Searching online results in an indication to Encode BER to DER and then the ToPEM will not throw this annoying error.
I couldn't find any solution whatsoever.

The pfx file is encoded with base64 and decoded to []byte which doesn't suppose to affect the error in any case.

I don't have any option to change the pfx file which is inserted into this variable config.ClusterCertificate

The code:

blocks, err := pkcs12.ToPEM(config.ClusterCertificate, "")
	if err != nil {
		return nil, err
	}
	var pemData []byte
	for _, b := range blocks {
		pemData = append(pemData, pem.EncodeToMemory(b)...)
	}

	// then use PEM data for tls to construct tls certificate:
	cert, err := tls.X509KeyPair(pemData, pemData)
	if err != nil {
		return nil, err
	}

	config := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	_ = config

	x509cert, err := x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		return nil, err
	}
	store.TrustStore = x509cert
	store.Certificate = &cert

`go.mod file not found in current directory or any parent directory.` when `go get`

> go get -u software.sslmate.com/src/go-pkcs12
go: go.mod file not found in current directory or any parent directory.            
        'go get' is no longer supported outside a module.                          
        To build and install a command, use 'go install' with a version,           
        like 'go install example.com/cmd@latest'                                   
        For more information, see https://golang.org/doc/go-get-install-deprecation
        or run 'go help get' or 'go help install'. 

The generated pfx format certificate cannot be used in the tomcat program.

func Encode ----
The generated pfx format certificate cannot be used in the tomcat program, which will directly cause the tomcat program to fail to start. I have tried many encoding rules, but the problem cannot be solved?
I suspect that the tomcat program's certificate generation rules on the pfx format certificate are different from the rules for generating certificates on the IIS web service for encoding certificates.
image

<Connector            protocol="org.apache.coyote.http11.Http11NioProtocol"            port="443" maxThreads="200"            scheme="https" secure="true" SSLEnabled="true"            keystoreFile="xxx.com.pfx" keystorePass="4Y2LOv50" keystoreType="PKCS12"            clientAuth="false" sslProtocol="TLS"/>

Encoding a combined keystore and trust store

Moin,

I've been wrestling with a library - march_hare - for a while. I need to provide TLS certificates to march_hare, so march_hare can connect to a TLS secured RabbitMQ instance in order to do messaging stuff.

In order to generate these certs from Hashicorp Vault, we have written a small internal tool called the certdeployer. This tool uses the vault API on one side and has a config files to write the certificates into files in pretty much whatever format we need - encoding/pem in three files (ca/key/cert), key and cert bundled, pkcs8, and so on.

This library is used (very successfully) to generate PKCS12 Keystores and Truststores for our java applications via the Encode and EncodeTrustEntries functions and then they can connect to postgres/rabbitmq/whatever.

However, march_hare is throwing a new wrench into the gears, because march_hare does not use a keystore and a truststore like many other applications. Instead, march hare wants one PKCS12 keystore, which in turn contains one key/cert safebag, and one trust-entry safebag with the CA.

Now after some back and forth I kinda bit the bullet and setup a quick and dirty PoC on a fork of kinda merging Encode and EncodeTrustEntries and this results in a keystore that actually works fine, at least in the keystore explorer. You can find the current kludge here:

https://github.com/Tetha/go-pkcs12/blob/combined-key-and-trust-store/pkcs12_combined.go

And like the biggest ordeal in this process was getting the two safebag lists appended right here:

https://github.com/Tetha/go-pkcs12/blob/combined-key-and-trust-store/pkcs12_combined.go#L124

Now, what I'd like to know from you is if you want this merged? If you do, I'd have to clean the code up a little, probably by extracting the safebag creations into reusable functions and adding a few tests. Things like that.

Support decoding pbeWithSHAAnd128BitRC2CBC

Currently library supports PBEWithSHAAnd40BitRC2CBC which generates 40 bit key
The library does not support pbeWithSHAAnd128BitRC2CBC which generates 128 bit key

Shall we add support for this algorithm.

Friendly name for `Encode()`

EncodeTrustStore() supports using the CN as the friendly name. Encode() does not. Is there a chance it can be added?

If you use openssl, you can do it for key+cert, not just truststore (cert-only); actually you can provide the friendly name separately, which might be an even easier solution:

openssl pkcs12 -export -in cert.pem -inkey key.pem -name "friendlyName" -out new.p12

So perhaps:

func EncodeTrustStore(rand Reader, certs []*x509Certificate, password, friendlyName string) (pfxData []byte, err error)
func Encode(rand Reader, privateKey interface{}, certs []*x509Certificate, password, friendlyName string) (pfxData []byte, err error)

MAC data iteration

Can we possibly have mac iteration as a parameter to the Encode() function? It seems like openssl has 2048 MAC iterations

`DecodeChain` assumes the certificate chain order is from the leaf to root

I'm new to the cryptography area, and I'd like to post some stupid question here.

I'm using this package to decode a pfx exported from Azure Key Vault, where the PEM blocks after decoding is in the order of: private key -> root cert -> intermidiary cert -> leaf cert. The DecodeChain returns the root cert as the certficate.

The document of this function clearly states that:

The first certificate is assumed to be the leaf certificate, and subsequent certificates, if any, are assumed to comprise the CA certificate chain.

It is obvious that I can manually tweak the returned certificate and caCerts as I already know my pfx is in the reverse order as is expected by this API. Whilst I'd like to see if there is an idiomatic way to achieve this. Even better, is there a way I can tell which order the current pfx is in, and conditionally apply the order reversing. Does it make sense to embed above ordering things to this API so that it can handle both orders?

Single item Authenticated Safe support

Hi there,

I have a use case that is currently unsupported but would like to get implemented if possible.
I am working with an Authenticode code signing certificate issued by DigiCert.
When using decode chain the decode fails as exactly two items are expected in the Authenticated Safe.

It appears that the implementation this is based on had all the certificate bags in one item in the Authenticated Safe and then the PKCS8ShroundedKeyBag in a separate bag under a separate item in the Authenticated Safe, but the PFX PDU that I am using has the shrouded key and all of the cert bags together in a single item within the Safe.

The error is thrown in getSafeContents in pkcs12.go here https://github.com/SSLMate/go-pkcs12/blob/01f6600bb3869be1db8ab7b801c02a76dc56280d/pkcs12.go#L406C2-L406C2 , it would appear from the spec https://www.rfc-editor.org/rfc/rfc7292 that the possibility of >=1 items in the Authenticated Safe is a possibility.

I would be happy to put together a pull request and discuss further if this sounds like something you would like to incorporate.

Thanks.

Java 18 PKCS12 keystore format

Java 18 migrates the cacerts keystore from JKS to a password-less PKCS12 format file. See the release notes and bug details.

When the data from this file is passed to Decode*, the library throws a no MAC in data error. The release notes also state:
"All certificates inside are not encrypted and there is no MacData for password integrity"

Is it possible to add support for this new format?

Support frientlyName in DecodeChain

We wish to have access to friendlyName for every object in a pkcs12.
We have seen problems where frientlyName differed between private and public keys, and would like to be able to validate and visualize this.

Thanks for your work with this package :)

Error in parsing encrypted private key

I am getting the following error when I try to parse an encrypted key
panic: pkcs12: error parsing PKCS#8 private key: x509: PKCS#8 wrapping contained private key with unknown algorithm: 1.2.840.10040.4.1

What could be the issue

x509: RSA key missing NULL parameters

I have a PKCS 12 file including:

  • one certificate
  • one private key

Screenshot 2021-03-01 at 17 56 13

What I simply do is:

  1. Read my p12 file
  2. Decode the p12 file
certFile, err := ioutil.ReadFile("authentication.p12")
privateKey, cert, err := pkcs12.Decode(certFile, "my_password")

The error returned from pkcs12 library is the following:
x509: RSA key missing NULL parameters

Is the problem related to the standard used by this library implementation?

Support triple DES certificate encryption

OpenSSL 3 throws an error of legacy algorithm when trying to parse P12 that uses RC2 to encrypt its certificates.

I would like to have the ability to encrypt the certificates with triple DES when generating P12. Pretty much an equivalent to the "-descert" flag of openssl.

I have created a proposal for this functionality in #35.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.