Skip to content

Commit dd6f075

Browse files
committed
[ca] add private server certificate generation support
1 parent 065612b commit dd6f075

File tree

7 files changed

+91
-61
lines changed

7 files changed

+91
-61
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/android-sms-gateway/cli
33
go 1.23.2
44

55
require (
6-
github.com/android-sms-gateway/client-go v1.5.5-0.20250309004612-ebfc247ebb13
6+
github.com/android-sms-gateway/client-go v1.5.5
77
github.com/capcom6/go-helpers v0.0.0-20240521035631-865ee2879fa3
88
github.com/joho/godotenv v1.5.1
99
github.com/urfave/cli/v2 v2.27.5

go.sum

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
github.com/android-sms-gateway/client-go v1.4.1-0.20250131044630-1de6b5ecb49f h1:7qhIHF6Kytfa1ln0ww46nJIFwxzHkINK7atkE8cLSJM=
2-
github.com/android-sms-gateway/client-go v1.4.1-0.20250131044630-1de6b5ecb49f/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
3-
github.com/android-sms-gateway/client-go v1.5.0 h1:CDREtWU2Z85dW7JcsW3a+vKZkj9g2Buq8vlrnEdGaoE=
4-
github.com/android-sms-gateway/client-go v1.5.0/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
5-
github.com/android-sms-gateway/client-go v1.5.5-0.20250307091924-1076d115eb88 h1:LmcJ8zpxKTHtwBLkQcmn1pEIgPEDCH5bY9ukYQAf+1c=
6-
github.com/android-sms-gateway/client-go v1.5.5-0.20250307091924-1076d115eb88/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
71
github.com/android-sms-gateway/client-go v1.5.5-0.20250309004612-ebfc247ebb13 h1:OSPmpOeLtU10zULCNuSJ6ouuwlKZlBaxYEs5vxknPWI=
82
github.com/android-sms-gateway/client-go v1.5.5-0.20250309004612-ebfc247ebb13/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
3+
github.com/android-sms-gateway/client-go v1.5.5 h1:38ykCT1g+w3dW7ZNDeX1qyfZuvXI5h19MP/WFg4Rodw=
4+
github.com/android-sms-gateway/client-go v1.5.5/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
95
github.com/capcom6/go-helpers v0.0.0-20240521035631-865ee2879fa3 h1:mq9rmBMCCzqGnZtbQqFSd+Ua3fahqUOYaTf26YFhWJc=
106
github.com/capcom6/go-helpers v0.0.0-20240521035631-865ee2879fa3/go.mod h1:WDqc7HZNqHxUTisArkYIBZtqUfJBVyPWeQI+FMwEzAw=
117
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=

internal/commands/ca/ca.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ import (
66

77
var Commands = []*cli.Command{
88
webhooks,
9+
private,
910
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package common
2+
3+
import (
4+
"crypto/x509"
5+
"crypto/x509/pkix"
6+
"net"
7+
"net/netip"
8+
9+
"github.com/android-sms-gateway/cli/internal/core/codes"
10+
"github.com/android-sms-gateway/client-go/ca"
11+
"github.com/urfave/cli/v2"
12+
)
13+
14+
// NewIPCertificateCommand creates a new CLI command for generating an IP certificate
15+
// of the specified type
16+
func NewIPCertificateCommand(name, usage string, aliases []string, typ ca.CSRType) *cli.Command {
17+
return &cli.Command{
18+
Name: name,
19+
Aliases: aliases,
20+
Usage: usage,
21+
Args: true,
22+
ArgsUsage: "Server IP address",
23+
Flags: []cli.Flag{
24+
&cli.StringFlag{
25+
Name: "out",
26+
Usage: "Certificate output file",
27+
Required: false,
28+
Value: "server.crt",
29+
},
30+
&cli.StringFlag{
31+
Name: "keyout",
32+
Usage: "Private key output file",
33+
Required: false,
34+
Value: "server.key",
35+
},
36+
},
37+
Action: func(c *cli.Context) error {
38+
ip := c.Args().Get(0)
39+
if ip == "" {
40+
return cli.Exit("IP address is empty", codes.ParamsError)
41+
}
42+
43+
netipAddr, err := netip.ParseAddr(ip)
44+
if err != nil {
45+
return cli.Exit(err.Error(), codes.ParamsError)
46+
}
47+
48+
if !netipAddr.IsPrivate() {
49+
return cli.Exit("IP address is not private", codes.ParamsError)
50+
}
51+
52+
csrTemplate := x509.CertificateRequest{
53+
Subject: pkix.Name{
54+
CommonName: netipAddr.String(),
55+
},
56+
IPAddresses: []net.IP{netipAddr.AsSlice()},
57+
}
58+
59+
return requestCertificate(c, typ, csrTemplate)
60+
},
61+
}
62+
63+
}

internal/commands/ca/utils.go renamed to internal/commands/ca/common/utils.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ca
1+
package common
22

33
import (
44
"crypto/ecdsa"
@@ -41,7 +41,7 @@ func newServerCertificateRequestPEM(template x509.CertificateRequest, priv *ecds
4141
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}), nil
4242
}
4343

44-
func requestCertificate(c *cli.Context, template x509.CertificateRequest) error {
44+
func requestCertificate(c *cli.Context, typ ca.CSRType, template x509.CertificateRequest) error {
4545
log.Println("Generating private key...")
4646
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
4747
if err != nil {
@@ -68,6 +68,7 @@ func requestCertificate(c *cli.Context, template x509.CertificateRequest) error
6868
client := metadata.GetCAClient(c.App.Metadata)
6969

7070
resp, err := client.PostCSR(c.Context, ca.PostCSRRequest{
71+
Type: typ,
7172
Content: string(csrPemBytes),
7273
})
7374
if err != nil {

internal/commands/ca/private.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package ca
2+
3+
import (
4+
"github.com/android-sms-gateway/cli/internal/commands/ca/common"
5+
"github.com/android-sms-gateway/client-go/ca"
6+
)
7+
8+
var private = common.NewIPCertificateCommand(
9+
"private",
10+
"Issue a new certificate for Private server",
11+
[]string{"p"},
12+
ca.CSRTypePrivateServer,
13+
)

internal/commands/ca/webhooks.go

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,13 @@
11
package ca
22

33
import (
4-
"crypto/x509"
5-
"crypto/x509/pkix"
6-
"net"
7-
"net/netip"
8-
9-
"github.com/android-sms-gateway/cli/internal/core/codes"
10-
"github.com/urfave/cli/v2"
4+
"github.com/android-sms-gateway/cli/internal/commands/ca/common"
5+
"github.com/android-sms-gateway/client-go/ca"
116
)
127

13-
var webhooks = &cli.Command{
14-
Name: "webhooks",
15-
Aliases: []string{"wh"},
16-
Usage: "Issue a new certificate for receiving webhooks to local IP address",
17-
Args: true,
18-
ArgsUsage: "IP address",
19-
Flags: []cli.Flag{
20-
&cli.StringFlag{
21-
Name: "out",
22-
Usage: "Certificate output file",
23-
Required: false,
24-
Value: "server.crt",
25-
},
26-
&cli.StringFlag{
27-
Name: "keyout",
28-
Usage: "Private key output file",
29-
Required: false,
30-
Value: "server.key",
31-
},
32-
},
33-
Action: func(c *cli.Context) error {
34-
ip := c.Args().Get(0)
35-
if ip == "" {
36-
return cli.Exit("IP address is empty", codes.ParamsError)
37-
}
38-
39-
netipAddr, err := netip.ParseAddr(ip)
40-
if err != nil {
41-
return cli.Exit(err.Error(), codes.ParamsError)
42-
}
43-
44-
if !netipAddr.IsPrivate() {
45-
return cli.Exit("IP address is not private", codes.ParamsError)
46-
}
47-
48-
csrTemplate := x509.CertificateRequest{
49-
Subject: pkix.Name{
50-
CommonName: netipAddr.String(),
51-
},
52-
IPAddresses: []net.IP{netipAddr.AsSlice()},
53-
}
54-
55-
return requestCertificate(c, csrTemplate)
56-
},
57-
}
8+
var webhooks = common.NewIPCertificateCommand(
9+
"webhooks",
10+
"Issue a new certificate for receiving webhooks to local IP address",
11+
[]string{"wh"},
12+
ca.CSRTypeWebhook,
13+
)

0 commit comments

Comments
 (0)