Skip to content

Commit f53d6d8

Browse files
authored
Merge pull request #2 from madflojo/tempfiles
Adding ability to create random files
2 parents fbcecb0 + ac25887 commit f53d6d8

File tree

3 files changed

+259
-47
lines changed

3 files changed

+259
-47
lines changed

README.md

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,82 @@
44
[![Coverage Status](https://coveralls.io/repos/github/madflojo/testcerts/badge.svg?branch=master)](https://coveralls.io/github/madflojo/testcerts?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/madflojo/testcerts)](https://goreportcard.com/report/github.com/madflojo/testcerts) [![Documentation](https://godoc.org/github.com/madflojo/testcerts?status.svg)](http://godoc.org/github.com/madflojo/testcerts)
55
[![license](https://img.shields.io/github/license/madflojo/testcerts.svg?maxAge=2592000)](https://github.com/madflojo/testcerts/LICENSE)
66

7-
A Go package for creating temporary x509 test certificates
7+
testcerts is a Go package that makes it easy for developers to generate x509 certificates for testing and development purposes. The package provides an easy-to-use API for generating self-signed certificates and keys for testing.
88

9-
There are many Certificate generation tools out there, but most focus on being a CLI tool. This package is focused on providing helper functions for creating Certificates. These helper functions can be used as part of Go tests per the example below.
9+
What makes testcerts unique is its ability to generate certificates and keys with a single line of code, and also its ability to handle saving them to temp and non-temp files, which eliminates the need for developers to handle file operations while testing their code.
10+
11+
Overall, testcerts simplifies the process of generating and managing test certificates, making it a valuable tool for any developer working with x509 certificates.
12+
13+
## Usage
14+
15+
### Generating Certificates to File
16+
17+
The `GenerateCertsToFile` function generates an X.509 certificate and key and writes them to the file paths provided.
1018

1119
```go
12-
func TestSomething(t *testing.T) {
13-
err := testcerts.GenerateCertsToFile("/tmp/cert", "/tmp/key")
14-
if err != nil {
15-
// do stuff
16-
}
17-
18-
_ = something.Run("/tmp/cert", "/tmp/key")
19-
// do more testing
20+
package main
21+
22+
import (
23+
"github.com/madflojo/testcerts"
24+
)
25+
26+
func main() {
27+
err := testcerts.GenerateCertsToFile("/tmp/cert.pem", "/tmp/key.pem")
28+
if err != nil {
29+
// handle error
30+
}
2031
}
2132
```
2233

23-
The goal of this package, is to make testing TLS based services easier. Without having to leave the comfort of your editor, or place test certificates in your repo.
34+
### Generating Certificates to Temporary File
35+
36+
The `GenerateCertsToTempFile` function generates an X.509 certificate and key and writes them to randomly generated files in the directory provided or the system's temporary directory if none is provided. The function returns the file paths of the generated files.
37+
38+
```go
39+
package main
40+
41+
import (
42+
"github.com/madflojo/testcerts"
43+
)
44+
45+
func main() {
46+
certFile, keyFile, err := testcerts.GenerateCertsToTempFile("/tmp/")
47+
if err != nil {
48+
// handle error
49+
}
50+
}
51+
```
52+
53+
### Generating Certificates
54+
55+
The `GenerateCerts` function generates an X.509 certificate and key and returns them as byte slices.
56+
57+
```go
58+
package main
59+
60+
import (
61+
"fmt"
62+
63+
"github.com/madflojo/testcerts"
64+
)
65+
66+
func main() {
67+
cert, key, err := testcerts.GenerateCerts()
68+
if err != nil {
69+
// handle error
70+
}
71+
fmt.Printf("Certificate: %s\n", cert)
72+
fmt.Printf("Key: %s\n", key)
73+
}
74+
```
75+
76+
## Contributing
77+
78+
If you find a bug or have an idea for a feature, please open an issue or a pull request.
79+
80+
## License
81+
82+
testcerts is released under the MIT License. See [LICENSE](./LICENSE) for details.
83+
84+
85+

testcerts.go

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
// Package testcerts enables users to create temporary x509 Certificates for testing.
2-
//
3-
// There are many Certificate generation tools out there, but most focus on being a CLI tool. This package is focused
4-
// on providing helper functions for creating Certificates. These helper functions can be used as part of your unit
5-
// and integration tests as per the example below.
6-
//
7-
// func TestSomething(t *testing.T) {
8-
// err := testcerts.GenerateCertsToFile("/tmp/cert", "/tmp/key")
9-
// if err != nil {
10-
// // do stuff
11-
// }
12-
//
13-
// _ = something.Run("/tmp/cert", "/tmp/key")
14-
// // do more testing
15-
// }
16-
//
17-
// The goal of this package, is to make testing TLS based services easier. Without having to leave the comfort of your
18-
// editor, or place test certificates in your repo.
1+
/*
2+
Package testcerts provides a set of functions for generating and saving x509 test certificates to file.
3+
4+
This package can be used in testing and development environments where a set of trusted certificates are needed.
5+
The main function, GenerateCertsToTempFile, generates an x509 certificate and key and writes them to a randomly
6+
named file in a specified or temporary directory.
7+
8+
For example, to generate and save a certificate and key to a temporary directory:
9+
10+
package main
11+
12+
import (
13+
"fmt"
14+
"log"
15+
16+
"testcerts"
17+
)
18+
19+
func main() {
20+
certPath, keyPath, err := testcerts.GenerateCertsToTempFile("")
21+
if err != nil {
22+
log.Fatal(err)
23+
}
24+
fmt.Println("Certificate written to:", certPath)
25+
fmt.Println("Key written to:", keyPath)
26+
}
27+
28+
This will create a temporary certificate and key and print the paths to where the files were written.
29+
*/
1930
package testcerts
2031

2132
import (
@@ -30,11 +41,12 @@ import (
3041
"time"
3142
)
3243

33-
// GenerateCerts will create a temporary x509 Certificate and Key.
44+
// GenerateCerts generates an x509 certificate and key.
45+
// It returns the certificate and key as byte slices, and any error that occurred.
3446
//
3547
// cert, key, err := GenerateCerts()
3648
// if err != nil {
37-
// // do stuff
49+
// // handle error
3850
// }
3951
func GenerateCerts() ([]byte, []byte, error) {
4052
// Create certs and return as []byte
@@ -45,44 +57,85 @@ func GenerateCerts() ([]byte, []byte, error) {
4557
return pem.EncodeToMemory(c), pem.EncodeToMemory(k), nil
4658
}
4759

48-
// GenerateCertsToFile will create a temporary x509 Certificate and Key. Writing them to the file provided.
60+
// GenerateCertsToFile creates an x509 certificate and key and writes it to the specified file paths.
4961
//
5062
// err := GenerateCertsToFile("/path/to/cert", "/path/to/key")
5163
// if err != nil {
52-
// // do stuff
64+
// // handle error
5365
// }
66+
//
67+
// If the specified file paths already exist, it will overwrite the existing files.
5468
func GenerateCertsToFile(certFile, keyFile string) error {
5569
// Create Certs
56-
c, k, err := genCerts()
70+
c, k, err := GenerateCerts()
5771
if err != nil {
5872
return err
5973
}
6074

61-
// Write to Certificate File
75+
// Write Certificate
6276
cfh, err := os.Create(certFile)
6377
if err != nil {
6478
return fmt.Errorf("unable to create certificate file - %s", err)
6579
}
6680
defer cfh.Close()
67-
err = pem.Encode(cfh, c)
81+
_, err = cfh.Write(c)
6882
if err != nil {
6983
return fmt.Errorf("unable to create certificate file - %s", err)
7084
}
7185

72-
// Write to Key File
86+
// Write Key
7387
kfh, err := os.Create(keyFile)
7488
if err != nil {
7589
return fmt.Errorf("unable to create certificate file - %s", err)
7690
}
7791
defer kfh.Close()
78-
err = pem.Encode(kfh, k)
92+
_, err = kfh.Write(k)
7993
if err != nil {
8094
return fmt.Errorf("unable to create certificate file - %s", err)
8195
}
8296

8397
return nil
8498
}
8599

100+
// GenerateCertsToTempFile will create a temporary x509 certificate and key in a randomly generated file using the
101+
// directory path provided. If no directory is specified, the default directory for temporary files as returned by
102+
// os.TempDir will be used.
103+
//
104+
// cert, key, err := GenerateCertsToTempFile("/tmp/")
105+
// if err != nil {
106+
// // handle error
107+
// }
108+
func GenerateCertsToTempFile(dir string) (string, string, error) {
109+
// Create Certs
110+
c, k, err := GenerateCerts()
111+
if err != nil {
112+
return "", "", err
113+
}
114+
115+
cfh, err := os.CreateTemp(dir, "*.cert")
116+
if err != nil {
117+
return "", "", fmt.Errorf("could not create temporary file - %s", err)
118+
}
119+
defer cfh.Close()
120+
_, err = cfh.Write(c)
121+
if err != nil {
122+
return cfh.Name(), "", fmt.Errorf("unable to create certificate file - %s", err)
123+
}
124+
125+
// Write to Key File
126+
kfh, err := os.CreateTemp(dir, "*.key")
127+
if err != nil {
128+
return cfh.Name(), "", fmt.Errorf("unable to create certificate file - %s", err)
129+
}
130+
defer kfh.Close()
131+
_, err = kfh.Write(k)
132+
if err != nil {
133+
return cfh.Name(), kfh.Name(), fmt.Errorf("unable to create certificate file - %s", err)
134+
}
135+
136+
return cfh.Name(), kfh.Name(), nil
137+
}
138+
86139
// genCerts will perform the task of creating a temporary Certificate and Key.
87140
func genCerts() (*pem.Block, *pem.Block, error) {
88141
// Create a Certificate Authority Cert
@@ -101,14 +154,14 @@ func genCerts() (*pem.Block, *pem.Block, error) {
101154
// Create a Private Key
102155
key, err := rsa.GenerateKey(rand.Reader, 4096)
103156
if err != nil {
104-
return nil, nil, fmt.Errorf("Could not generate rsa key - %s", err)
157+
return nil, nil, fmt.Errorf("could not generate rsa key - %s", err)
105158
}
106159

107160
// Use CA Cert to sign a CSR and create a Public Cert
108161
csr := &key.PublicKey
109162
cert, err := x509.CreateCertificate(rand.Reader, ca, ca, csr, key)
110163
if err != nil {
111-
return nil, nil, fmt.Errorf("Could not generate certificate - %s", err)
164+
return nil, nil, fmt.Errorf("could not generate certificate - %s", err)
112165
}
113166

114167
// Convert keys into pem.Block

0 commit comments

Comments
 (0)