72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
package req
|
|
|
|
import(
|
|
"os"
|
|
"fmt"
|
|
"crypto/x509"
|
|
"crypto/ecdsa"
|
|
"crypto/rand"
|
|
"crypto/elliptic"
|
|
"encoding/base64"
|
|
"encoding/pem"
|
|
"encoding/asn1"
|
|
)
|
|
type CSRContainer struct{
|
|
CSR string // Данные CSR в виде строки (PEM-блок и base64).
|
|
PrivateKey string // Секретный ключ (PEM-блок и base64).
|
|
}
|
|
type subjectTemplate struct{
|
|
Subject subjectSet `asn1:"set"`
|
|
}
|
|
type subjectSet struct{
|
|
CN subjectCN
|
|
}
|
|
type subjectCN struct{
|
|
OID asn1.ObjectIdentifier
|
|
Value string `asn1:"utf8"`
|
|
}
|
|
func CraftCSRandKey(name string) (CSRContainer, bool){
|
|
var res CSRContainer
|
|
var sT subjectTemplate
|
|
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to generate private key: %s\n\n", err.Error())
|
|
return res, false
|
|
}
|
|
sT.Subject.CN = subjectCN{
|
|
OID : []int{ 0x02, 0x05, 0x04, 0x03 },
|
|
Value : name,
|
|
}
|
|
nameRaw, err := asn1.Marshal(sT)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to generate private key: %s\n\n", err.Error())
|
|
return res, false
|
|
}
|
|
var csrTemplate = x509.CertificateRequest {
|
|
RawSubject : nameRaw,
|
|
SignatureAlgorithm : x509.ECDSAWithSHA256,
|
|
}
|
|
csr, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, privKey)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to generate CSR: %s\n\n", err.Error())
|
|
return res, false
|
|
}
|
|
exportKey, err := x509.MarshalECPrivateKey(privKey)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to marshal private key: %s\n\n", err.Error())
|
|
return res, false
|
|
}
|
|
block := &pem.Block{
|
|
Type: "EC PRIVATE KEY",
|
|
Bytes: exportKey,
|
|
}
|
|
pemEncodedKey := pem.EncodeToMemory(block)
|
|
if pemEncodedKey == nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to generate PEM for key: %s\n\n", err.Error())
|
|
return res, false
|
|
}
|
|
res.CSR = "-----BEGIN CERTIFICATE REQUEST-----" + base64.StdEncoding.EncodeToString(csr) + "-----END CERTIFICATE REQUEST-----"
|
|
res.PrivateKey = string(pemEncodedKey)
|
|
return res, true
|
|
}
|