MCPcopy Create free account
hub / github.com/0xUnixIO/pulse / SignCSR

Method SignCSR

internal/cert/ca.go:186–235  ·  view source on GitHub ↗

SignCSR signs the given PEM-encoded CSR producing a node client certificate whose CommonName is forced to nodeID. The CSR's self-reported subject is not trusted; only its public key and signature are used.

(csrPEM []byte, nodeID string, ttl time.Duration)

Source from the content-addressed store, hash-verified

184// whose CommonName is forced to nodeID. The CSR's self-reported subject is not
185// trusted; only its public key and signature are used.
186func (ca *NodeCA) SignCSR(csrPEM []byte, nodeID string, ttl time.Duration) ([]byte, error) {
187 if nodeID == "" {
188 return nil, fmt.Errorf("node id is required")
189 }
190 if ttl <= 0 {
191 return nil, fmt.Errorf("ttl must be positive")
192 }
193
194 block, _ := pem.Decode(csrPEM)
195 if block == nil || block.Type != "CERTIFICATE REQUEST" {
196 return nil, fmt.Errorf("decode CSR PEM: invalid block")
197 }
198 csr, err := x509.ParseCertificateRequest(block.Bytes)
199 if err != nil {
200 return nil, fmt.Errorf("parse CSR: %w", err)
201 }
202 if err := csr.CheckSignature(); err != nil {
203 return nil, fmt.Errorf("verify CSR signature: %w", err)
204 }
205
206 serial, err := randomSerial()
207 if err != nil {
208 return nil, err
209 }
210
211 uri := &url.URL{Scheme: "pulse-node", Host: nodeID}
212
213 now := time.Now()
214 template := &x509.Certificate{
215 SerialNumber: serial,
216 Subject: pkix.Name{
217 CommonName: nodeID,
218 Organization: []string{"pulse-node"},
219 },
220 NotBefore: now.Add(-time.Minute),
221 NotAfter: now.Add(ttl),
222 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
223 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
224 BasicConstraintsValid: true,
225 IsCA: false,
226 URIs: []*url.URL{uri},
227 }
228
229 der, err := x509.CreateCertificate(rand.Reader, template, ca.cert, csr.PublicKey, ca.key)
230 if err != nil {
231 return nil, fmt.Errorf("sign certificate: %w", err)
232 }
233
234 return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der}), nil
235}
236
237// CertPEM returns the CA's own certificate in PEM form. Safe to share with
238// nodes (used as RootCA for verifying the server when establishing mTLS).

Callers 6

TestSignCSR_SuccessFunction · 0.80
TestSignCSR_InvalidPEMFunction · 0.80
TestSignCSR_BadSignatureFunction · 0.80
RegisterEnrollEndpointFunction · 0.80
newMockServerFunction · 0.80

Calls 2

randomSerialFunction · 0.85
AddMethod · 0.80

Tested by 5

TestSignCSR_SuccessFunction · 0.64
TestSignCSR_InvalidPEMFunction · 0.64
TestSignCSR_BadSignatureFunction · 0.64
newMockServerFunction · 0.64