tcibot/req/req.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
}