Added support for ECDH in enveloped data with ECDSA certificates.
- fixed parsing of choice(was compatible with Apple mail.app which tagged kari explicitly) - minor fixes
This commit is contained in:
@ -4,26 +4,29 @@ package openssl
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SMIME is the commpand used for openssl smime, can be replaces with cms
|
||||
var SMIME = "smime"
|
||||
|
||||
//Encrypt a message with openssl
|
||||
func Encrypt(in []byte, cert *x509.Certificate, opts ...string) (der []byte, err error) {
|
||||
|
||||
tmp, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmp.Name())
|
||||
tmpKey, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpKey.Name())
|
||||
|
||||
pem.Encode(tmp, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
|
||||
|
||||
param := []string{"smime", "-encrypt", "-aes128"}
|
||||
param := []string{SMIME, "-encrypt", "-aes128"}
|
||||
param = append(param, opts...)
|
||||
param = append(param, tmp.Name())
|
||||
param = append(param, tmpKey.Name())
|
||||
der, err = openssl(in, param...)
|
||||
|
||||
return
|
||||
@ -32,20 +35,24 @@ func Encrypt(in []byte, cert *x509.Certificate, opts ...string) (der []byte, err
|
||||
//Decrypt a message with openssl
|
||||
func Decrypt(in []byte, key crypto.PrivateKey, opts ...string) (plain []byte, err error) {
|
||||
|
||||
tmp, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmp.Name())
|
||||
tmpKey, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpKey.Name())
|
||||
|
||||
pem.Encode(tmp, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key.(*rsa.PrivateKey))})
|
||||
keyDER, err := x509.MarshalPKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})
|
||||
|
||||
param := []string{"smime", "-decrypt"}
|
||||
param := []string{SMIME, "-decrypt"}
|
||||
param = append(param, opts...)
|
||||
param = append(param, []string{"-decrypt", "-inkey", tmp.Name()}...)
|
||||
param = append(param, []string{"-inkey", tmpKey.Name()}...)
|
||||
plain, err = openssl(in, param...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//Create a detached signature with openssl
|
||||
// SignDetached creates a detached signature with openssl
|
||||
func SignDetached(in []byte, cert *x509.Certificate, key crypto.PrivateKey, interm []*x509.Certificate, opts ...string) (plain []byte, err error) {
|
||||
|
||||
tmpCert, err := ioutil.TempFile("", "example")
|
||||
@ -56,7 +63,11 @@ func SignDetached(in []byte, cert *x509.Certificate, key crypto.PrivateKey, inte
|
||||
tmpKey, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpKey.Name())
|
||||
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key.(*rsa.PrivateKey))})
|
||||
keyDER, err := x509.MarshalPKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})
|
||||
|
||||
tmpInterm, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpInterm.Name())
|
||||
@ -65,7 +76,7 @@ func SignDetached(in []byte, cert *x509.Certificate, key crypto.PrivateKey, inte
|
||||
pem.Encode(tmpInterm, &pem.Block{Type: "CERTIFICATE", Bytes: i.Raw})
|
||||
}
|
||||
|
||||
param := []string{"smime", "-sign", "-nodetach"}
|
||||
param := []string{SMIME, "-sign", "-nodetach"}
|
||||
param = append(param, opts...)
|
||||
param = append(param, []string{"-signer", tmpCert.Name(), "-inkey", tmpKey.Name(), "-certfile", tmpInterm.Name()}...)
|
||||
plain, err = openssl(in, param...)
|
||||
@ -73,7 +84,7 @@ func SignDetached(in []byte, cert *x509.Certificate, key crypto.PrivateKey, inte
|
||||
return
|
||||
}
|
||||
|
||||
//Create a signature with openssl
|
||||
// Sign creates a signature with openssl
|
||||
func Sign(in []byte, cert *x509.Certificate, key crypto.PrivateKey, interm []*x509.Certificate, opts ...string) (plain []byte, err error) {
|
||||
|
||||
tmpCert, err := ioutil.TempFile("", "example")
|
||||
@ -84,7 +95,11 @@ func Sign(in []byte, cert *x509.Certificate, key crypto.PrivateKey, interm []*x5
|
||||
tmpKey, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpKey.Name())
|
||||
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key.(*rsa.PrivateKey))})
|
||||
keyDER, err := x509.MarshalPKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pem.Encode(tmpKey, &pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})
|
||||
|
||||
tmpInterm, err := ioutil.TempFile("", "example")
|
||||
defer os.Remove(tmpInterm.Name())
|
||||
@ -93,7 +108,7 @@ func Sign(in []byte, cert *x509.Certificate, key crypto.PrivateKey, interm []*x5
|
||||
pem.Encode(tmpInterm, &pem.Block{Type: "CERTIFICATE", Bytes: i.Raw})
|
||||
}
|
||||
|
||||
param := []string{"smime", "-sign"}
|
||||
param := []string{SMIME, "-sign"}
|
||||
param = append(param, opts...)
|
||||
param = append(param, []string{"-signer", tmpCert.Name(), "-inkey", tmpKey.Name(), "-certfile", tmpInterm.Name()}...)
|
||||
plain, err = openssl(in, param...)
|
||||
@ -109,7 +124,7 @@ func Verify(in []byte, ca *x509.Certificate, opts ...string) (plain []byte, err
|
||||
|
||||
pem.Encode(tmpCA, &pem.Block{Type: "CERTIFICATE", Bytes: ca.Raw})
|
||||
|
||||
param := []string{"smime", "-verify"}
|
||||
param := []string{SMIME, "-verify"}
|
||||
param = append(param, opts...)
|
||||
param = append(param, []string{"-CAfile", tmpCA.Name()}...)
|
||||
plain, err = openssl(in, param...)
|
||||
@ -117,6 +132,11 @@ func Verify(in []byte, ca *x509.Certificate, opts ...string) (plain []byte, err
|
||||
return
|
||||
}
|
||||
|
||||
// Openssl runs the openssl command with given args
|
||||
func Openssl(stdin []byte, args ...string) ([]byte, error) {
|
||||
return openssl(stdin, args...)
|
||||
}
|
||||
|
||||
func openssl(stdin []byte, args ...string) ([]byte, error) {
|
||||
cmd := exec.Command("openssl", args...)
|
||||
|
||||
@ -133,5 +153,9 @@ func openssl(stdin []byte, args ...string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if strings.Contains(errs.String(), "Error") {
|
||||
return nil, fmt.Errorf("error running %s (%s):\n ", cmd.Args, errs.String())
|
||||
}
|
||||
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user