]> Cypherpunks.ru repositories - ucspi.git/blob - x509.go
Unify copyright comment format
[ucspi.git] / x509.go
1 // ucspi -- UCSPI-related utilities
2 // Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package ucspi
17
18 import (
19         "crypto/x509"
20         "encoding/pem"
21         "errors"
22         "os"
23 )
24
25 func CertificateFromFile(p string) (b []byte, c *x509.Certificate, err error) {
26         var data []byte
27         data, err = os.ReadFile(p)
28         if err != nil {
29                 return
30         }
31         var block *pem.Block
32         for len(data) > 0 {
33                 block, data = pem.Decode(data)
34                 if block == nil {
35                         continue
36                 }
37                 if block.Type == "CERTIFICATE" {
38                         b = block.Bytes
39                         c, err = x509.ParseCertificate(b)
40                         return
41                 }
42         }
43         err = errors.New("no CERTIFICATE found in PEM")
44         return
45 }
46
47 func PrivateKeyFromFile(p string) (prv interface{}, err error) {
48         var data []byte
49         data, err = os.ReadFile(p)
50         if err != nil {
51                 return
52         }
53         var block *pem.Block
54         for len(data) > 0 {
55                 block, data = pem.Decode(data)
56                 if block == nil {
57                         continue
58                 }
59                 switch block.Type {
60                 case "PRIVATE KEY":
61                         prv, err = x509.ParsePKCS8PrivateKey(block.Bytes)
62                         return
63                 case "EC PRIVATE KEY":
64                         prv, err = x509.ParseECPrivateKey(block.Bytes)
65                         return
66                 }
67         }
68         err = errors.New("no PRIVATE KEY found in PEM")
69         return
70 }
71
72 func CertPoolFromFile(p string) (certs []*x509.Certificate, pool *x509.CertPool, err error) {
73         var data []byte
74         data, err = os.ReadFile(p)
75         if err != nil {
76                 return
77         }
78         pool = x509.NewCertPool()
79         var block *pem.Block
80         for len(data) > 0 {
81                 block, data = pem.Decode(data)
82                 if block == nil {
83                         err = errors.New("can not decode PEM")
84                         return
85                 }
86                 if block.Type != "CERTIFICATE" {
87                         err = errors.New("non CERTIFICATE found in PEM")
88                         return
89                 }
90                 var ca *x509.Certificate
91                 ca, err = x509.ParseCertificate(block.Bytes)
92                 if err != nil {
93                         return
94                 }
95                 certs = append(certs, ca)
96                 pool.AddCert(ca)
97         }
98         return
99 }