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 }