MCPcopy Create free account
hub / github.com/XTLS/Go / X509KeyPair

Function X509KeyPair

tls.go:245–334  ·  view source on GitHub ↗

X509KeyPair parses a public/private key pair from a pair of PEM encoded data. On successful return, Certificate.Leaf will be nil because the parsed form of the certificate is not retained.

(certPEMBlock, keyPEMBlock []byte)

Source from the content-addressed store, hash-verified

243// PEM encoded data. On successful return, Certificate.Leaf will be nil because
244// the parsed form of the certificate is not retained.
245func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
246 fail := func(err error) (Certificate, error) { return Certificate{}, err }
247
248 var cert Certificate
249 var skippedBlockTypes []string
250 for {
251 var certDERBlock *pem.Block
252 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
253 if certDERBlock == nil {
254 break
255 }
256 if certDERBlock.Type == "CERTIFICATE" {
257 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
258 } else {
259 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
260 }
261 }
262
263 if len(cert.Certificate) == 0 {
264 if len(skippedBlockTypes) == 0 {
265 return fail(errors.New("tls: failed to find any PEM data in certificate input"))
266 }
267 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
268 return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
269 }
270 return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
271 }
272
273 skippedBlockTypes = skippedBlockTypes[:0]
274 var keyDERBlock *pem.Block
275 for {
276 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
277 if keyDERBlock == nil {
278 if len(skippedBlockTypes) == 0 {
279 return fail(errors.New("tls: failed to find any PEM data in key input"))
280 }
281 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
282 return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
283 }
284 return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
285 }
286 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
287 break
288 }
289 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
290 }
291
292 // We don't need to parse the public key for TLS, but we so do anyway
293 // to check that it looks sane and matches the private key.
294 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
295 if err != nil {
296 return fail(err)
297 }
298
299 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
300 if err != nil {
301 return fail(err)
302 }

Callers 1

LoadX509KeyPairFunction · 0.85

Calls 1

parsePrivateKeyFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…