From d09c7fa8fc21cdc1ca6aa30821335b26c1612cfe Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 15 Apr 2024 19:36:35 -0400
Subject: [PATCH 01/54] update README for Cert Warden

---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 10ea261..119a724 100644
--- a/README.md
+++ b/README.md
@@ -86,12 +86,12 @@ for passing the pem content from another application without having
 to save the pem files to disk.
 
 Putting all of this together, you can combine the install binary with 
-a tool like LeGo CertHub (https://www.legocerthub.com/) to call the 
+a tool like Cert Warden (https://www.certwarden.com/) to call the 
 install binary, with environment variables, to directly upload new 
-certificates as they're issued by LeGo, without having to write a 
+certificates as they're issued by Cert Warden, without having to write a 
 separate script.
 
-![LeGo CertHub with APC P15 Tool](https://raw.githubusercontent.com/gregtwallace/apc-p15-tool/main/img/apc-p15-tool.png)
+![Cert Warden with APC P15 Tool](https://raw.githubusercontent.com/gregtwallace/apc-p15-tool/main/img/apc-p15-tool.png)
 
 ## Thanks
 

From ecf10f1fdc4f06fe8061018b07ea71aa61f88421 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 18:59:35 -0400
Subject: [PATCH 02/54] go: update to 1.22.3

---
 go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index 5d6ca7f..d5bd69a 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.22.1
+go 1.22.3
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From 01be6ca577cf5fb2b1d5ed12006d6f227c01dbc1 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 18:59:36 -0400
Subject: [PATCH 03/54] add p15 key output file

The NMC Security Wizard can also produce .p15 files that contain just a private key. Add this ability to this tool.

When the `create` function is used, both files will be outputted.
---
 pkg/app/cmd_create.go    |  31 ++++--
 pkg/app/cmd_install.go   |   2 +-
 pkg/app/config.go        |   6 +-
 pkg/app/file_header.go   |   4 +-
 pkg/app/pem_to_p15.go    |  20 ++--
 pkg/pkcs15/pem_to_p15.go | 230 ++++++++++++++++++++++++++++-----------
 6 files changed, 206 insertions(+), 87 deletions(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index 51cf1cc..bc9ecdf 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -6,7 +6,10 @@ import (
 	"os"
 )
 
-const createDefaultOutFilePath = "apctool.p15"
+const (
+	createDefaultOutFilePath    = "apctool.p15"
+	createDefaultOutKeyFilePath = "apctool.key.p15"
+)
 
 // cmdCreate is the app's command to create an apc p15 file from key and cert
 // pem files
@@ -26,25 +29,35 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 
 	// validation done
 
-	// make p15 file
-	apcFile, err := app.pemToAPCP15(keyPem, certPem, "create")
+	// make p15 files
+	apcKeyCertFile, keyFile, err := app.pemToAPCP15s(keyPem, certPem, "create")
 	if err != nil {
 		return err
 	}
 
 	// determine file name (should already be done by flag parsing, but avoid nil just in case)
-	fileName := createDefaultOutFilePath
+	keyCertFileName := createDefaultOutFilePath
 	if app.config.create.outFilePath != nil && *app.config.create.outFilePath != "" {
-		fileName = *app.config.create.outFilePath
+		keyCertFileName = *app.config.create.outFilePath
 	}
 
-	// write file
-	err = os.WriteFile(fileName, apcFile, 0777)
+	keyFileName := createDefaultOutFilePath
+	if app.config.create.outKeyFilePath != nil && *app.config.create.outKeyFilePath != "" {
+		keyFileName = *app.config.create.outKeyFilePath
+	}
+
+	// write files
+	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0777)
 	if err != nil {
-		return fmt.Errorf("create: failed to write apc p15 file (%s)", err)
+		return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 	}
+	app.stdLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileName)
 
-	app.stdLogger.Printf("create: apc p15 file %s written to disk", fileName)
+	err = os.WriteFile(keyFileName, keyFile, 0777)
+	if err != nil {
+		return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
+	}
+	app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
 
 	return nil
 }
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index 5d826ec..26635e7 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -52,7 +52,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	// validation done
 
 	// make p15 file
-	apcFile, err := app.pemToAPCP15(keyPem, certPem, "install")
+	apcFile, _, err := app.pemToAPCP15s(keyPem, certPem, "install")
 	if err != nil {
 		return err
 	}
diff --git a/pkg/app/config.go b/pkg/app/config.go
index 6514391..bea67aa 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -28,7 +28,8 @@ type config struct {
 	debugLogging *bool
 	create       struct {
 		keyCertPemCfg
-		outFilePath *string
+		outFilePath    *string
+		outKeyFilePath *string
 	}
 	install struct {
 		keyCertPemCfg
@@ -71,7 +72,8 @@ func (app *app) getConfig(args []string) error {
 	cfg.create.certPemFilePath = createFlags.StringLong("certfile", "", "path and filename of the certificate in pem format")
 	cfg.create.keyPem = createFlags.StringLong("keypem", "", "string of the rsa-1024 or rsa-2048 key in pem format")
 	cfg.create.certPem = createFlags.StringLong("certpem", "", "string of the certificate in pem format")
-	cfg.create.outFilePath = createFlags.StringLong("outfile", createDefaultOutFilePath, "path and filename to write the p15 file to")
+	cfg.create.outFilePath = createFlags.StringLong("outfile", createDefaultOutFilePath, "path and filename to write the key+cert p15 file to")
+	cfg.create.outKeyFilePath = createFlags.StringLong("outkeyfile", createDefaultOutKeyFilePath, "path and filename to write the key p15 file to")
 
 	createCmd := &ff.Command{
 		Name:      "create",
diff --git a/pkg/app/file_header.go b/pkg/app/file_header.go
index b803d68..20097cd 100644
--- a/pkg/app/file_header.go
+++ b/pkg/app/file_header.go
@@ -7,6 +7,8 @@ import (
 	"github.com/sigurn/crc16"
 )
 
+const apcHeaderLen = 228
+
 // makeFileHeader generates the 228 byte header to prepend to the .p15
 // as required by APC UPS NMC. Contrary to the apc_tools repo, it does
 // mot appear the header changes based on key size.
@@ -28,7 +30,7 @@ func makeFileHeader(p15File []byte) ([]byte, error) {
 	// 		*(uint32_t *)(buf + 208) = keySize; // 1 for 1024 key, otherwise (2048 bit) 2
 	// Unsure why this was in original code but seems irrelevant
 
-	header := make([]byte, 228)
+	header := make([]byte, apcHeaderLen)
 
 	// always 1
 	header[0] = 1
diff --git a/pkg/app/pem_to_p15.go b/pkg/app/pem_to_p15.go
index eb020aa..b006c9e 100644
--- a/pkg/app/pem_to_p15.go
+++ b/pkg/app/pem_to_p15.go
@@ -5,34 +5,36 @@ import (
 	"fmt"
 )
 
-// pemToAPCP15 reads the specified pem files and returns the apc p15 bytes
-func (app *app) pemToAPCP15(keyPem, certPem []byte, parentCmdName string) ([]byte, error) {
+// pemToAPCP15s reads the specified pem files and returns the apc p15 files (both a
+// p15 file with just the private key, and also a p15 file with both the private key
+// and certificate). The key+cert file includes the required APC header, prepended.
+func (app *app) pemToAPCP15s(keyPem, certPem []byte, parentCmdName string) (apcKeyCertFile, keyFile []byte, err error) {
 	app.stdLogger.Printf("%s: making apc p15 file from pem", parentCmdName)
 
 	// make p15 struct
 	p15, err := pkcs15.ParsePEMToPKCS15(keyPem, certPem)
 	if err != nil {
-		return nil, fmt.Errorf("%s: failed to parse pem files (%w)", parentCmdName, err)
+		return nil, nil, fmt.Errorf("%s: failed to parse pem files (%w)", parentCmdName, err)
 	}
 
 	app.stdLogger.Printf("%s: successfully loaded pem files", parentCmdName)
 
 	// make file bytes
-	p15File, err := p15.ToP15File()
+	keyCertFile, keyFile, err := p15.ToP15Files()
 	if err != nil {
-		return nil, fmt.Errorf("%s: failed to make p15 file (%w)", parentCmdName, err)
+		return nil, nil, fmt.Errorf("%s: failed to make p15 file (%w)", parentCmdName, err)
 	}
 
 	// make header for file bytes
-	apcHeader, err := makeFileHeader(p15File)
+	apcHeader, err := makeFileHeader(keyCertFile)
 	if err != nil {
-		return nil, fmt.Errorf("%s: failed to make p15 file header (%w)", parentCmdName, err)
+		return nil, nil, fmt.Errorf("%s: failed to make p15 file header (%w)", parentCmdName, err)
 	}
 
 	// combine header with file
-	apcFile := append(apcHeader, p15File...)
+	apcKeyCertFile = append(apcHeader, keyCertFile...)
 
 	app.stdLogger.Printf("%s: apc p15 file data succesfully generated", parentCmdName)
 
-	return apcFile, nil
+	return apcKeyCertFile, keyFile, nil
 }
diff --git a/pkg/pkcs15/pem_to_p15.go b/pkg/pkcs15/pem_to_p15.go
index a7a9fef..19392f2 100644
--- a/pkg/pkcs15/pem_to_p15.go
+++ b/pkg/pkcs15/pem_to_p15.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"encoding/asn1"
 	"math/big"
 )
 
@@ -9,62 +10,11 @@ const (
 	apcKeyLabel = "Private key"
 )
 
-// ToP15File turns the key and cert into a properly formatted and encoded
-// p15 file
-func (p15 *pkcs15KeyCert) ToP15File() ([]byte, error) {
+// toP15KeyCert creates a P15 file with both the private key and certificate, mirroring the
+// final p15 file an APC UPS expects (though without the header)
+func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err error) {
 	// private key object
-	pkey, err := p15.toP15PrivateKey()
-	if err != nil {
-		return nil, err
-	}
-
-	cert, err := p15.toP15Cert()
-	if err != nil {
-		return nil, err
-	}
-
-	// ContentInfo
-	p15File := asn1obj.Sequence([][]byte{
-
-		// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
-		asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
-
-		// content
-		asn1obj.ExplicitCompound(0, [][]byte{
-			asn1obj.Sequence([][]byte{
-				asn1obj.Integer(big.NewInt(0)),
-				asn1obj.Sequence([][]byte{
-					asn1obj.ExplicitCompound(0, [][]byte{
-						asn1obj.ExplicitCompound(0, [][]byte{
-							pkey,
-						}),
-					}),
-					asn1obj.ExplicitCompound(4, [][]byte{
-						asn1obj.ExplicitCompound(0, [][]byte{
-							cert,
-						}),
-					}),
-				}),
-			}),
-		}),
-	})
-
-	return p15File, nil
-}
-
-// toP15PrivateKey creates the encoded private key. it is broken our from the larger p15
-// function for readability
-// NOTE: Do not use this to try and turn just a private key into a p15, the format isn't
-// quite the same.
-func (p15 *pkcs15KeyCert) toP15PrivateKey() ([]byte, error) {
-	// rsa encrypted key in encrypted envelope
-	envelope, err := p15.encryptedKeyEnvelope()
-	if err != nil {
-		return nil, err
-	}
-
-	// key object
-	key := asn1obj.Sequence([][]byte{
+	privateKey := asn1obj.Sequence([][]byte{
 		// commonObjectAttributes - Label
 		asn1obj.Sequence([][]byte{
 			asn1obj.UTF8String(apcKeyLabel),
@@ -87,20 +37,12 @@ func (p15 *pkcs15KeyCert) toP15PrivateKey() ([]byte, error) {
 			asn1obj.Sequence([][]byte{
 				// AuthEnvelopedData Type ([4])
 				asn1obj.ExplicitCompound(4, [][]byte{
-					envelope,
+					keyEnvelope,
 				}),
 			}),
 		}),
 	})
 
-	return key, nil
-}
-
-// toP15Cert creates the encoded certificate. it is broken our from the larger p15
-// function for readability
-// NOTE: Do not use this to try and turn just a cert into a p15. I don't believe,
-// such a thing is permissible under the spec.
-func (p15 *pkcs15KeyCert) toP15Cert() ([]byte, error) {
 	// cert object
 	cert := asn1obj.Sequence([][]byte{
 		// commonObjectAttributes - Label
@@ -134,5 +76,163 @@ func (p15 *pkcs15KeyCert) toP15Cert() ([]byte, error) {
 		}),
 	})
 
-	return cert, nil
+	// build the file
+
+	// ContentInfo
+	keyCert = asn1obj.Sequence([][]byte{
+
+		// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
+		asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
+
+		// content
+		asn1obj.ExplicitCompound(0, [][]byte{
+			asn1obj.Sequence([][]byte{
+				asn1obj.Integer(big.NewInt(0)),
+				asn1obj.Sequence([][]byte{
+					asn1obj.ExplicitCompound(0, [][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							privateKey,
+						}),
+					}),
+					asn1obj.ExplicitCompound(4, [][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							cert,
+						}),
+					}),
+				}),
+			}),
+		}),
+	})
+
+	return keyCert, nil
+}
+
+// toP15Key creates a P15 file with just the private key, mirroring the p15 format
+// the APC tool uses when generating a new private key (Note: no header is used on
+// this file)
+func (p15 *pkcs15KeyCert) toP15Key(keyEnvelope []byte) (key []byte, err error) {
+	// private key object (slightly different than the key+cert format)
+	privateKey := asn1obj.Sequence([][]byte{
+		// commonObjectAttributes - Label
+		asn1obj.Sequence([][]byte{
+			asn1obj.UTF8String(apcKeyLabel),
+		}),
+		// CommonKeyAttributes
+		asn1obj.Sequence([][]byte{
+			// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
+			asn1obj.OctetString(p15.keyId()),
+			// CommonKeyAttributes - usage (trailing 0s will drop)
+			asn1obj.BitString([]byte{byte(0b11100010)}),
+			// CommonKeyAttributes - accessFlags (trailing 0s will drop)
+			asn1obj.BitString([]byte{byte(0b10110000)}),
+		}),
+
+		//
+		asn1obj.ExplicitCompound(0, [][]byte{
+			asn1obj.Sequence([][]byte{
+				asn1obj.ExplicitCompound(0, [][]byte{
+					p15.keyIdInt2(),
+					p15.keyIdInt8(),
+					p15.keyIdInt9(),
+				}),
+			}),
+		}),
+
+		// ObjectValue - indirect-protected
+		asn1obj.ExplicitCompound(1, [][]byte{
+			asn1obj.Sequence([][]byte{
+				// AuthEnvelopedData Type ([4])
+				asn1obj.ExplicitCompound(4, [][]byte{
+					keyEnvelope,
+				}),
+			}),
+		}),
+	})
+
+	// ContentInfo
+	key = asn1obj.Sequence([][]byte{
+
+		// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
+		asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
+
+		// content
+		asn1obj.ExplicitCompound(0, [][]byte{
+			asn1obj.Sequence([][]byte{
+				asn1obj.Integer(big.NewInt(0)),
+				asn1obj.Sequence([][]byte{
+					// [0] Private Key
+					asn1obj.ExplicitCompound(0, [][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							privateKey,
+						}),
+					}),
+					// [1] Public Key
+					asn1obj.ExplicitCompound(1, [][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							asn1obj.Sequence([][]byte{
+								// commonObjectAttributes - Label
+								asn1obj.Sequence([][]byte{
+									asn1obj.UTF8String(apcKeyLabel),
+								}),
+								// CommonKeyAttributes
+								asn1obj.Sequence([][]byte{
+									asn1obj.OctetString(p15.keyId()),
+									asn1obj.BitString([]byte{byte(0b10000010)}),
+									asn1obj.BitString([]byte{byte(0b01000000)}),
+								}),
+
+								asn1obj.ExplicitCompound(1, [][]byte{
+									asn1obj.Sequence([][]byte{
+										asn1obj.ExplicitCompound(0, [][]byte{
+											asn1obj.ExplicitCompound(1, [][]byte{
+												asn1obj.Sequence([][]byte{
+													asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
+													asn1.NullBytes,
+												}),
+												// RSAPublicKey SubjectPublicKeyInfo
+												asn1obj.BitString(
+													asn1obj.Sequence([][]byte{
+														asn1obj.Integer(p15.key.PublicKey.N),
+														asn1obj.Integer(big.NewInt(int64(p15.key.PublicKey.E))),
+													}),
+												),
+											}),
+										}),
+										// not 100% certain but appears to be rsa key byte len
+										asn1obj.Integer(big.NewInt(int64(p15.key.PublicKey.N.BitLen() / 8))),
+									}),
+								}),
+							}),
+						}),
+					}),
+				}),
+			}),
+		}),
+	})
+
+	return key, nil
+}
+
+// ToP15File turns the key and cert into a properly formatted and encoded
+// p15 file
+func (p15 *pkcs15KeyCert) ToP15Files() (keyCertFile []byte, keyFile []byte, err error) {
+	// rsa encrypted key in encrypted envelope (will be shared by both output files)
+	envelope, err := p15.encryptedKeyEnvelope()
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// key + cert file
+	keyCertFile, err = p15.toP15KeyCert(envelope)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// key only file
+	keyFile, err = p15.toP15Key(envelope)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return keyCertFile, keyFile, nil
 }

From da84a7b0852fbbfc97a73d8a885556ad14fd2d15 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 18:59:36 -0400
Subject: [PATCH 04/54] debug: add base64 encoded debug files

When troubleshooting it is helpful to put the generated files into an asn1 decoder. The files can be copy/pasted easily in b64 format.

This change creates b64 files when the debug flag is set to make this process easier.
---
 .gitignore            |  1 +
 pkg/app/cmd_create.go | 27 +++++++++++++++++++++++++++
 pkg/app/config.go     |  2 +-
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 9e11ecb..6cd9c9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 # key/cert files
 *.p15
 *.pem
+*.b64
 
 # ignore test_data folder
 /_test_data
diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index bc9ecdf..46b239c 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -2,6 +2,7 @@ package app
 
 import (
 	"context"
+	"encoding/base64"
 	"fmt"
 	"os"
 )
@@ -59,5 +60,31 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	}
 	app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
 
+	// if debug, write additional debug files (b64 format to make copy/paste into asn1 decoder
+	// easy to do e.g., https://lapo.it/asn1js)
+	if app.config.debugLogging != nil && *app.config.debugLogging {
+		keyCertFileNameDebug := keyCertFileName + ".noheader.b64"
+		err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0777)
+		if err != nil {
+			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+		}
+		app.debugLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileNameDebug)
+
+		keyCertFileNameHeaderDebug := keyCertFileName + ".header.b64"
+		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0777)
+		if err != nil {
+			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+		}
+		app.debugLogger.Printf("create: apc p15 key+cert file header %s written to disk", keyCertFileNameHeaderDebug)
+
+		keyFileNameDebug := keyFileName + ".b64"
+		err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0777)
+		if err != nil {
+			return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
+		}
+		app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
+
+	}
+
 	return nil
 }
diff --git a/pkg/app/config.go b/pkg/app/config.go
index bea67aa..e8ff1fc 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -57,7 +57,7 @@ func (app *app) getConfig(args []string) error {
 	// apc-p15-tool -- root command
 	rootFlags := ff.NewFlagSet("apc-p15-tool")
 
-	cfg.debugLogging = rootFlags.BoolLong("debug", "set this flag to enable additional debug logging messages")
+	cfg.debugLogging = rootFlags.BoolLong("debug", "set this flag to enable additional debug logging messages and files")
 
 	rootCmd := &ff.Command{
 		Name:  "apc-p15-tool",

From f0253ccaf219379df5686c5b5491cfe0a45befb3 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 18:59:36 -0400
Subject: [PATCH 05/54] create: set file permissiosns to owner only

---
 pkg/app/cmd_create.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index 46b239c..c6b6750 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -48,13 +48,13 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	}
 
 	// write files
-	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0777)
+	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0600)
 	if err != nil {
 		return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 	}
 	app.stdLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileName)
 
-	err = os.WriteFile(keyFileName, keyFile, 0777)
+	err = os.WriteFile(keyFileName, keyFile, 0600)
 	if err != nil {
 		return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
 	}
@@ -64,21 +64,21 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	// easy to do e.g., https://lapo.it/asn1js)
 	if app.config.debugLogging != nil && *app.config.debugLogging {
 		keyCertFileNameDebug := keyCertFileName + ".noheader.b64"
-		err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0777)
+		err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
 		if err != nil {
 			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 		}
 		app.debugLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileNameDebug)
 
 		keyCertFileNameHeaderDebug := keyCertFileName + ".header.b64"
-		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0777)
+		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
 		if err != nil {
 			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 		}
 		app.debugLogger.Printf("create: apc p15 key+cert file header %s written to disk", keyCertFileNameHeaderDebug)
 
 		keyFileNameDebug := keyFileName + ".b64"
-		err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0777)
+		err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0600)
 		if err != nil {
 			return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
 		}

From b44b49cd19c3a1d80fc3a7147ece2edb6a25ec7c Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 18:59:36 -0400
Subject: [PATCH 06/54] create: add additional flag to signal creation of
 additional key.p15

---
 pkg/app/cmd_create.go | 26 ++++++++++++++++----------
 pkg/app/config.go     |  2 ++
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index c6b6750..ad31003 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -47,19 +47,13 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 		keyFileName = *app.config.create.outKeyFilePath
 	}
 
-	// write files
+	// write file(s)
 	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0600)
 	if err != nil {
 		return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 	}
 	app.stdLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileName)
 
-	err = os.WriteFile(keyFileName, keyFile, 0600)
-	if err != nil {
-		return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
-	}
-	app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
-
 	// if debug, write additional debug files (b64 format to make copy/paste into asn1 decoder
 	// easy to do e.g., https://lapo.it/asn1js)
 	if app.config.debugLogging != nil && *app.config.debugLogging {
@@ -77,13 +71,25 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 		}
 		app.debugLogger.Printf("create: apc p15 key+cert file header %s written to disk", keyCertFileNameHeaderDebug)
 
-		keyFileNameDebug := keyFileName + ".b64"
-		err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0600)
+	}
+
+	// make key p15 ?
+	if app.config.create.makeKeyP15 != nil && *app.config.create.makeKeyP15 {
+		err = os.WriteFile(keyFileName, keyFile, 0600)
 		if err != nil {
 			return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
 		}
-		app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
+		app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
 
+		// debug file ?
+		if app.config.debugLogging != nil && *app.config.debugLogging {
+			keyFileNameDebug := keyFileName + ".b64"
+			err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0600)
+			if err != nil {
+				return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
+			}
+			app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
+		}
 	}
 
 	return nil
diff --git a/pkg/app/config.go b/pkg/app/config.go
index e8ff1fc..a3b18c1 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -29,6 +29,7 @@ type config struct {
 	create       struct {
 		keyCertPemCfg
 		outFilePath    *string
+		makeKeyP15     *bool
 		outKeyFilePath *string
 	}
 	install struct {
@@ -73,6 +74,7 @@ func (app *app) getConfig(args []string) error {
 	cfg.create.keyPem = createFlags.StringLong("keypem", "", "string of the rsa-1024 or rsa-2048 key in pem format")
 	cfg.create.certPem = createFlags.StringLong("certpem", "", "string of the certificate in pem format")
 	cfg.create.outFilePath = createFlags.StringLong("outfile", createDefaultOutFilePath, "path and filename to write the key+cert p15 file to")
+	cfg.create.makeKeyP15 = createFlags.BoolLong("keyp15", "create a second p15 file with just the private key")
 	cfg.create.outKeyFilePath = createFlags.StringLong("outkeyfile", createDefaultOutKeyFilePath, "path and filename to write the key p15 file to")
 
 	createCmd := &ff.Command{

From 7dcf0f10b99f592d7cdeb39598d038bddf481e47 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 19:00:56 -0400
Subject: [PATCH 07/54] create: fix header debug file

---
 pkg/app/cmd_create.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index ad31003..c5d700c 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -65,7 +65,7 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 		app.debugLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileNameDebug)
 
 		keyCertFileNameHeaderDebug := keyCertFileName + ".header.b64"
-		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
+		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[:apcHeaderLen])), 0600)
 		if err != nil {
 			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
 		}

From 7a415f5c85dabc5b479327eeef4894750a698f16 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 4 Jun 2024 19:01:45 -0400
Subject: [PATCH 08/54] v0.5.0-preview1

---
 CHANGELOG.md   | 26 +++++++++++++++++---------
 pkg/app/app.go |  2 +-
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ecfe84d..f1963c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,47 +1,55 @@
 # APC P15 Tool Changelog
 
+## [v0.5.0] - 2024-06-04
+
+Add functionality to additionally output a key.p15 file. This file
+format matches that of APC's NMC Security Wizard's key file output.
+(Use `create` and flag `--keyp15`.)
+
+Add creation of additional base64 encoded files when the `--debug`
+flag is used with `create`. This makes it easier to paste these
+encoded files into an ASN1 viewer to analyze them.
+
+Modify output file permissions to `0666` instead of `0777`.
+
+Update Go version to 1.22.3.
+
 ## [v0.4.2] - 2024-03-29
 
 Fix usage message. Thanks @k725.
 
-
 ## [v0.4.1] - 2024-03-06
 
 Update to Go 1.22.1, which includes some security fixes.
 
-
 ## [v0.4.0] - 2024-02-05
 
 Add `--restartwebui` flag to issue a reboot command to the webui
-after a new certificate is installed. This was not needed with 
+after a new certificate is installed. This was not needed with
 my NMC2, but I suspect some might need it to get the new certificate
 to actually load.
 
-
 ## [v0.3.3] - 2024-02-04
 
 Add `--insecurecipher` flag to enable aes128-cbc and 3des-cbc for
 older devices/firmwares. These ciphers are considered insecure and
-should be avoided. A better alternative is to update the device 
+should be avoided. A better alternative is to update the device
 firmware if possible.
 
-
 ## [v0.3.2] - 2024-02-04
 
 Add support for 1,024 bit RSA keys. These are not recommended! RSA
 1024 is generally considered to not be completely secure anymore.
 
 Add `diffie-hellman-group-exchange-sha256` key exchange algorithm
-which may be needed by some UPSes to connect via SSH to use the 
+which may be needed by some UPSes to connect via SSH to use the
 install command.
 
-
 ## [v0.3.1] - 2024-02-03
 
 Fixes debug logging always being on. App now accurately reflects
 the state of the --debug flag.
 
-
 ## [v0.3.0] - 2024-02-03
 
 Initial release.
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 3119334..5cd9ebe 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "0.4.2"
+	appVersion = "0.5.0"
 )
 
 // struct for receivers to use common app pieces

From 41efc56c6253c6256e861d0c93019abdb253f61a Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:12 -0400
Subject: [PATCH 09/54] ssh: clarify log error msg

---
 pkg/app/ssh_response.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/app/ssh_response.go b/pkg/app/ssh_response.go
index 3b44523..8068704 100644
--- a/pkg/app/ssh_response.go
+++ b/pkg/app/ssh_response.go
@@ -12,7 +12,7 @@ func sshCheckResponse(remoteOutPipe io.Reader) error {
 	buffer := make([]uint8, 1)
 	_, err := remoteOutPipe.Read(buffer)
 	if err != nil {
-		return fmt.Errorf("ssh: failed to make read output buffer (%w)", err)
+		return fmt.Errorf("ssh: failed to read output buffer (%w)", err)
 	}
 
 	responseType := buffer[0]

From 06c9263bc4866bfe9e0bd5ca8ccadcdce906e947 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:12 -0400
Subject: [PATCH 10/54] ssh: breakout ups ssh to its own package This was done
 for clearer separation of function. A subsequent update will (hopefully) make
 the SSL command more robust so it works for both NMC2 and NMC3.

The method for sending shell commands was also updated to use an interactive shell instead. This allows capturing responses of the commands which will be needed to deduce if devices are NMC2 or NMC3.
---
 go.mod                         |   2 +
 pkg/apcssh/client.go           | 134 +++++++++++++++++++++++++++++++++
 pkg/apcssh/cmd_restartwebui.go |  24 ++++++
 pkg/apcssh/scp.go              | 129 +++++++++++++++++++++++++++++++
 pkg/apcssh/shell.go            |  88 ++++++++++++++++++++++
 pkg/apcssh/shell_helpers.go    |  38 ++++++++++
 pkg/apcssh/ssl.go              |  15 ++++
 pkg/app/cmd_install.go         | 114 ++++------------------------
 pkg/app/ssh_resetwebui.go      |  45 -----------
 pkg/app/ssh_response.go        |  34 ---------
 pkg/app/ssh_scp.go             | 105 --------------------------
 11 files changed, 444 insertions(+), 284 deletions(-)
 create mode 100644 pkg/apcssh/client.go
 create mode 100644 pkg/apcssh/cmd_restartwebui.go
 create mode 100644 pkg/apcssh/scp.go
 create mode 100644 pkg/apcssh/shell.go
 create mode 100644 pkg/apcssh/shell_helpers.go
 create mode 100644 pkg/apcssh/ssl.go
 delete mode 100644 pkg/app/ssh_resetwebui.go
 delete mode 100644 pkg/app/ssh_response.go
 delete mode 100644 pkg/app/ssh_scp.go

diff --git a/go.mod b/go.mod
index d5bd69a..2ae4f6a 100644
--- a/go.mod
+++ b/go.mod
@@ -14,6 +14,8 @@ replace apc-p15-tool/cmd/install_only => /cmd/install_only
 
 replace apc-p15-tool/cmd/tool => /cmd/tool
 
+replace apc-p15-tool/pkg/apcssh => /pkg/apcssh
+
 replace apc-p15-tool/pkg/app => /pkg/app
 
 replace apc-p15-tool/pkg/pkcs15 => /pkg/pkcs15
diff --git a/pkg/apcssh/client.go b/pkg/apcssh/client.go
new file mode 100644
index 0000000..33b01d5
--- /dev/null
+++ b/pkg/apcssh/client.go
@@ -0,0 +1,134 @@
+package apcssh
+
+import (
+	"crypto/sha256"
+	"encoding/base64"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"log"
+	"net"
+	"runtime"
+	"strings"
+	"time"
+
+	"golang.org/x/crypto/ssh"
+)
+
+const (
+	apcSSHVer = 1
+
+	sshTimeout = 90 * time.Second
+)
+
+// APC UPS won't except Go's SSH "Run()" command as the format isn't quite
+// the same. Therefore, write a custom implementation instead of relying on
+// something like github.com/bramvdbogaerde/go-scp
+
+type Config struct {
+	Hostname          string
+	Username          string
+	Password          string
+	ServerFingerprint string
+	InsecureCipher    bool
+}
+
+// Client is an APC UPS SSH client
+type Client struct {
+	hostname string
+	sshCfg   *ssh.ClientConfig
+}
+
+// New creates a new SSH Client for the APC UPS.
+func New(cfg *Config) (*Client, error) {
+	// make host key callback
+	hk := func(_hostname string, _remote net.Addr, key ssh.PublicKey) error {
+		// calculate server's key's SHA256
+		hasher := sha256.New()
+		_, err := hasher.Write(key.Marshal())
+		if err != nil {
+			return err
+		}
+		actualHash := hasher.Sum(nil)
+
+		// log fingerprint for debugging
+		actualHashB64 := base64.RawStdEncoding.EncodeToString(actualHash)
+		actualHashHex := hex.EncodeToString(actualHash)
+
+		// check for fingerprint match (b64 or hex)
+		if actualHashB64 != cfg.ServerFingerprint && actualHashHex != cfg.ServerFingerprint {
+			log.Printf("apcssh: remote server key fingerprint (b64): %s", actualHashB64)
+			log.Printf("apcssh: remote server key fingerprint (hex): %s", actualHashHex)
+
+			return errors.New("apcssh: fingerprint didn't match")
+		}
+
+		return nil
+	}
+
+	// kex algos
+	// see defaults: https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.18.0:ssh/common.go;l=62
+	kexAlgos := []string{
+		"curve25519-sha256", "curve25519-sha256@libssh.org",
+		"ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521",
+		"diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1",
+	}
+	// extra for some apc ups
+	kexAlgos = append(kexAlgos, "diffie-hellman-group-exchange-sha256")
+
+	// ciphers
+	// see defaults: https://cs.opensource.google/go/x/crypto/+/master:ssh/common.go;l=37
+	ciphers := []string{
+		"aes128-gcm@openssh.com", "aes256-gcm@openssh.com",
+		"chacha20-poly1305@openssh.com",
+		"aes128-ctr", "aes192-ctr", "aes256-ctr",
+	}
+
+	// insecure cipher options?
+	if cfg.InsecureCipher {
+		log.Println("WARNING: insecure ciphers are enabled (--insecurecipher). SSH with an insecure cipher is NOT secure and should NOT be used.")
+		ciphers = append(ciphers, "aes128-cbc", "3des-cbc")
+	}
+
+	// install file on UPS
+	// ssh config
+	config := &ssh.ClientConfig{
+		User: cfg.Username,
+		Auth: []ssh.AuthMethod{
+			ssh.Password(cfg.Password),
+		},
+		// APC seems to require `Client Version` string to start with "SSH-2" and must be at least
+		// 13 characters long
+		// working examples from other clients:
+		// ClientVersion: "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6",
+		// ClientVersion: "SSH-2.0-PuTTY_Release_0.80",
+		ClientVersion: fmt.Sprintf("SSH-2.0-apcssh_v%d %s-%s", apcSSHVer, runtime.GOOS, runtime.GOARCH),
+		Config: ssh.Config{
+			KeyExchanges: kexAlgos,
+			Ciphers:      ciphers,
+		},
+		HostKeyCallback: hk,
+
+		// reasonable timeout for file copy
+		Timeout: sshTimeout,
+	}
+
+	// if hostname missing a port, add default
+	if !strings.Contains(cfg.Hostname, ":") {
+		cfg.Hostname = cfg.Hostname + ":22"
+	}
+
+	// connect to ups over SSH (to verify everything works)
+	sshClient, err := ssh.Dial("tcp", cfg.Hostname, config)
+	if err != nil {
+		return nil, err
+	}
+	_ = sshClient.Close()
+
+	// return Client (note: new ssh Dial will be done for each action as the UPS
+	// seems to not do well with more than one Session per Dial)
+	return &Client{
+		hostname: cfg.Hostname,
+		sshCfg:   config,
+	}, nil
+}
diff --git a/pkg/apcssh/cmd_restartwebui.go b/pkg/apcssh/cmd_restartwebui.go
new file mode 100644
index 0000000..4b904c1
--- /dev/null
+++ b/pkg/apcssh/cmd_restartwebui.go
@@ -0,0 +1,24 @@
+package apcssh
+
+import (
+	"fmt"
+	"strings"
+)
+
+// RestartWebUI sends the APC command to restart the web ui
+// WARNING: Sending a command directly after this one will cause issues.
+// This command will cause SSH to also restart after a slight delay, therefore
+// any command right after this will start to run but then get stuck / fail
+// somewhere in the middle.
+func (cli *Client) RestartWebUI() error {
+	result, err := cli.cmd("reboot -Y")
+	if err != nil {
+		return err
+	}
+
+	if strings.ToLower(result.code) != "e000" {
+		return fmt.Errorf("apcssh: failed to restart web ui (%s: %s)", result.code, result.codeText)
+	}
+
+	return nil
+}
diff --git a/pkg/apcssh/scp.go b/pkg/apcssh/scp.go
new file mode 100644
index 0000000..9db77c0
--- /dev/null
+++ b/pkg/apcssh/scp.go
@@ -0,0 +1,129 @@
+package apcssh
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/fs"
+	"path"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// UploadSCP uploads a file to the destination specified (e.g., "/ssl/file.key")
+// containing the file content specified. An existing file at the destination
+// will be overwritten without warning.
+func (cli *Client) UploadSCP(destination string, fileContent []byte, filePermissions fs.FileMode) error {
+	// connect
+	sshClient, err := ssh.Dial("tcp", cli.hostname, cli.sshCfg)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to dial session (%w)", err)
+	}
+	defer sshClient.Close()
+
+	// make session to use for SCP
+	session, err := sshClient.NewSession()
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to create session (%w)", err)
+	}
+	defer session.Close()
+
+	// attach pipes
+	out, err := session.StdoutPipe()
+	if err != nil {
+		return err
+	}
+	w, err := session.StdinPipe()
+	if err != nil {
+		return err
+	}
+	defer w.Close()
+
+	// send execute cmd --
+	// build cmd to send as request
+	// Go implementation sends additional 0x22 bytes when using Run() (as
+	// compared to putty's scp tool). these additional bytes seem to cause the
+	// apc ups to fail execution of the command
+	payload := []byte(fmt.Sprintf("scp -q -t %s", destination))
+	payloadLen := uint8(len(payload))
+	payload = append([]byte{0, 0, 0, payloadLen}, payload...)
+
+	ok, err := session.SendRequest("exec", true, payload)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to execute scp cmd (%w)", err)
+	}
+	if !ok {
+		return errors.New("apcssh: scp: execute scp cmd not ok")
+	}
+
+	// check remote response
+	// Note: File upload may not work if the client doesn't actually read from
+	// the remote output.
+	err = scpCheckResponse(out)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send scp cmd (bad remote response 1) (%w)", err)
+	}
+
+	// just file name (without path)
+	filename := path.Base(destination)
+
+	// send file header
+	_, err = fmt.Fprintln(w, "C"+fmt.Sprintf("%04o", filePermissions.Perm()), len(fileContent), filename)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send file info (%w)", err)
+	}
+
+	err = scpCheckResponse(out)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send file info (bad remote response 2) (%w)", err)
+	}
+
+	// send actual file
+	_, err = io.Copy(w, bytes.NewReader(fileContent))
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send file(%w)", err)
+	}
+
+	// send file end
+	_, err = fmt.Fprint(w, "\x00")
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send final 00 byte (%w)", err)
+	}
+
+	err = scpCheckResponse(out)
+	if err != nil {
+		return fmt.Errorf("apcssh: scp: failed to send file (bad remote response 3) (%w)", err)
+	}
+
+	// done
+	return nil
+}
+
+// scpCheckResponse reads the output from the remote and returns an error
+// if the remote output was not 0
+func scpCheckResponse(remoteOutPipe io.Reader) error {
+	buffer := make([]uint8, 1)
+	_, err := remoteOutPipe.Read(buffer)
+	if err != nil {
+		return fmt.Errorf("apcssh: failed to read output buffer (%w)", err)
+	}
+
+	responseType := buffer[0]
+	message := ""
+	if responseType > 0 {
+		bufferedReader := bufio.NewReader(remoteOutPipe)
+		message, err = bufferedReader.ReadString('\n')
+		if err != nil {
+			return fmt.Errorf("apcssh: failed to read output buffer (%w)", err)
+		}
+	}
+
+	// if not 0 (aka OK)
+	if responseType != 0 {
+		return fmt.Errorf("apcssh: remote returned error (%d: %s)", responseType, message)
+	}
+
+	return nil
+}
diff --git a/pkg/apcssh/shell.go b/pkg/apcssh/shell.go
new file mode 100644
index 0000000..c6f082c
--- /dev/null
+++ b/pkg/apcssh/shell.go
@@ -0,0 +1,88 @@
+package apcssh
+
+import (
+	"bufio"
+	"fmt"
+	"strings"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// upsCmdResponse is a structure that holds all of a shell commands results
+type upsCmdResponse struct {
+	command    string
+	code       string
+	codeText   string
+	resultText string
+}
+
+// cmd creates an interactive shell and executes the specified command
+func (cli *Client) cmd(command string) (*upsCmdResponse, error) {
+	// connect
+	sshClient, err := ssh.Dial("tcp", cli.hostname, cli.sshCfg)
+	if err != nil {
+		return nil, fmt.Errorf("apcssh: failed to dial session (%w)", err)
+	}
+	defer sshClient.Close()
+
+	session, err := sshClient.NewSession()
+	if err != nil {
+		return nil, fmt.Errorf("apcssh: failed to create session (%w)", err)
+	}
+	defer session.Close()
+
+	// pipes to send shell command to; and to receive repsonse
+	sshInput, err := session.StdinPipe()
+	if err != nil {
+		return nil, fmt.Errorf("apcssh: failed to make shell input pipe (%w)", err)
+	}
+	sshOutput, err := session.StdoutPipe()
+	if err != nil {
+		return nil, fmt.Errorf("apcssh: failed to make shell output pipe (%w)", err)
+	}
+
+	// make scanner to read shell continuously
+	scanner := bufio.NewScanner(sshOutput)
+	scanner.Split(scanAPCShell)
+
+	// start interactive shell
+	if err := session.Shell(); err != nil {
+		return nil, fmt.Errorf("apcssh: failed to start shell (%w)", err)
+	}
+	// discard the initial shell response (login message(s) / initial shell prompt)
+	for {
+		if token := scanner.Scan(); token {
+			_ = scanner.Bytes()
+			break
+		}
+	}
+
+	// send command
+	_, err = fmt.Fprint(sshInput, command+"\n")
+	if err != nil {
+		return nil, fmt.Errorf("apcssh: failed to send shell command (%w)", err)
+	}
+
+	res := &upsCmdResponse{}
+	for {
+		if tkn := scanner.Scan(); tkn {
+			result := string(scanner.Bytes())
+
+			cmdIndx := strings.Index(result, "\n")
+			res.command = result[:cmdIndx-1]
+			result = result[cmdIndx+1:]
+
+			codeIndx := strings.Index(result, ": ")
+			res.code = result[:codeIndx]
+			result = result[codeIndx+2:]
+
+			codeTxtIndx := strings.Index(result, "\n")
+			res.codeText = result[:codeTxtIndx-1]
+
+			res.resultText = result[codeTxtIndx+1 : len(result)-2]
+			break
+		}
+	}
+
+	return res, nil
+}
diff --git a/pkg/apcssh/shell_helpers.go b/pkg/apcssh/shell_helpers.go
new file mode 100644
index 0000000..e2084cb
--- /dev/null
+++ b/pkg/apcssh/shell_helpers.go
@@ -0,0 +1,38 @@
+package apcssh
+
+import (
+	"regexp"
+)
+
+// scanAPCShell is a SplitFunc to capture shell output after each interactive
+// shell command is run
+func scanAPCShell(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+
+	// regex for shell prompt (e.g., `apc@apc>`)
+	re := regexp.MustCompile(`(\r\n|\r|\n)[A-Za-z0-0.]+@[A-Za-z0-0.]+>`)
+
+	// find match for prompt
+	if index := re.FindStringIndex(string(data)); index != nil {
+		// advance starts after the prompt; token is everything before the prompt
+		return index[1], dropCR(data[0:index[0]]), nil
+	}
+
+	// If we're at EOF, we have a final, non-terminated line. Return it.
+	if atEOF {
+		return len(data), dropCR(data), nil
+	}
+
+	// Request more data.
+	return 0, nil, nil
+}
+
+// dropCR drops a terminal \r from the data.
+func dropCR(data []byte) []byte {
+	if len(data) > 0 && data[len(data)-1] == '\r' {
+		return data[0 : len(data)-1]
+	}
+	return data
+}
diff --git a/pkg/apcssh/ssl.go b/pkg/apcssh/ssl.go
new file mode 100644
index 0000000..514545d
--- /dev/null
+++ b/pkg/apcssh/ssl.go
@@ -0,0 +1,15 @@
+package apcssh
+
+import "fmt"
+
+// InstallSSLCert installs the specified p15 cert file on the UPS. This
+// function currently only works on NMC2.
+func (cli *Client) InstallSSLCert(keyCertP15 []byte) error {
+	// install NMC2 P15 file
+	err := cli.UploadSCP("/ssl/defaultcert.p15", keyCertP15, 0600)
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send file to ups over scp (%w)", err)
+	}
+
+	return nil
+}
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index 26635e7..f59bd7b 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -1,16 +1,10 @@
 package app
 
 import (
+	"apc-p15-tool/pkg/apcssh"
 	"context"
-	"crypto/sha256"
-	"encoding/base64"
-	"encoding/hex"
 	"errors"
 	"fmt"
-	"net"
-	"runtime"
-
-	"golang.org/x/crypto/ssh"
 )
 
 // cmdInstall is the app's command to create apc p15 file content from key and cert
@@ -52,100 +46,29 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	// validation done
 
 	// make p15 file
-	apcFile, _, err := app.pemToAPCP15s(keyPem, certPem, "install")
+	keyCertP15, _, err := app.pemToAPCP15s(keyPem, certPem, "install")
 	if err != nil {
 		return err
 	}
 
-	// make host key callback
-	hk := func(hostname string, remote net.Addr, key ssh.PublicKey) error {
-		// calculate server's key's SHA256
-		hasher := sha256.New()
-		_, err := hasher.Write(key.Marshal())
-		if err != nil {
-			return err
-		}
-		actualHash := hasher.Sum(nil)
-
-		// log fingerprint for debugging
-		actualHashB64 := base64.RawStdEncoding.EncodeToString(actualHash)
-		actualHashHex := hex.EncodeToString(actualHash)
-		app.debugLogger.Printf("ssh: remote server key fingerprint (b64): %s", actualHashB64)
-		app.debugLogger.Printf("ssh: remote server key fingerprint (hex): %s", actualHashHex)
-
-		// allow base64 format
-		if actualHashB64 == *app.config.install.fingerprint {
-			return nil
-		}
-
-		// allow hex format
-		if actualHashHex == *app.config.install.fingerprint {
-			return nil
-		}
-
-		return errors.New("ssh: fingerprint didn't match")
+	// make APC SSH client
+	cfg := &apcssh.Config{
+		Hostname:          *app.config.install.hostAndPort,
+		Username:          *app.config.install.username,
+		Password:          *app.config.install.password,
+		ServerFingerprint: *app.config.install.fingerprint,
+		InsecureCipher:    *app.config.install.insecureCipher,
 	}
 
-	// kex algos
-	// see defaults: https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.18.0:ssh/common.go;l=62
-	kexAlgos := []string{
-		"curve25519-sha256", "curve25519-sha256@libssh.org",
-		"ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521",
-		"diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1",
-	}
-	// extra for some apc ups
-	kexAlgos = append(kexAlgos, "diffie-hellman-group-exchange-sha256")
-
-	// ciphers
-	// see defaults: https://cs.opensource.google/go/x/crypto/+/master:ssh/common.go;l=37
-	ciphers := []string{
-		"aes128-gcm@openssh.com", "aes256-gcm@openssh.com",
-		"chacha20-poly1305@openssh.com",
-		"aes128-ctr", "aes192-ctr", "aes256-ctr",
-	}
-
-	// insecure cipher options?
-	if app.config.install.insecureCipher != nil && *app.config.install.insecureCipher {
-		app.stdLogger.Println("WARNING: insecure ciphers are enabled (--insecurecipher). SSH with an insecure cipher is NOT secure and should NOT be used.")
-		ciphers = append(ciphers, "aes128-cbc", "3des-cbc")
-	}
-
-	// install file on UPS
-	// ssh config
-	config := &ssh.ClientConfig{
-		User: *app.config.install.username,
-		Auth: []ssh.AuthMethod{
-			ssh.Password(*app.config.install.password),
-		},
-		// APC seems to require `Client Version` string to start with "SSH-2" and must be at least
-		// 13 characters long
-		// working examples from other clients:
-		// ClientVersion: "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6",
-		// ClientVersion: "SSH-2.0-PuTTY_Release_0.80",
-		ClientVersion: fmt.Sprintf("SSH-2.0-apc-p15-tool_v%s %s-%s", appVersion, runtime.GOOS, runtime.GOARCH),
-		Config: ssh.Config{
-			KeyExchanges: kexAlgos,
-			Ciphers:      ciphers,
-			// MACs:         []string{"hmac-sha2-256"},
-		},
-		// HostKeyAlgorithms: []string{"ssh-rsa"},
-		HostKeyCallback: hk,
-
-		// reasonable timeout for file copy
-		Timeout: sshScpTimeout,
-	}
-
-	// connect to ups over SSH
-	client, err := ssh.Dial("tcp", *app.config.install.hostAndPort, config)
+	client, err := apcssh.New(cfg)
 	if err != nil {
 		return fmt.Errorf("install: failed to connect to host (%w)", err)
 	}
-	defer client.Close()
 
-	// send file to UPS
-	err = sshScpSendFileToUPS(client, apcFile)
+	// install SSL Cert
+	err = client.InstallSSLCert(keyCertP15)
 	if err != nil {
-		return fmt.Errorf("install: failed to send p15 file to ups over scp (%w)", err)
+		return fmt.Errorf("install: failed to send file to ups over scp (%w)", err)
 	}
 
 	// installed
@@ -155,16 +78,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	if app.config.install.restartWebUI != nil && *app.config.install.restartWebUI {
 		app.stdLogger.Println("install: sending restart command")
 
-		// connect to ups over SSH
-		// opening a second session doesn't seem to work with my NMC2 for some reason, so make
-		// a new connection instead
-		client, err = ssh.Dial("tcp", *app.config.install.hostAndPort, config)
-		if err != nil {
-			return fmt.Errorf("install: failed to reconnect to host to send webui restart command (%w)", err)
-		}
-		defer client.Close()
-
-		err = sshResetUPSWebUI(client)
+		err = client.RestartWebUI()
 		if err != nil {
 			return fmt.Errorf("install: failed to send webui restart command (%w)", err)
 		}
diff --git a/pkg/app/ssh_resetwebui.go b/pkg/app/ssh_resetwebui.go
deleted file mode 100644
index 52f90d9..0000000
--- a/pkg/app/ssh_resetwebui.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package app
-
-import (
-	"errors"
-	"fmt"
-
-	"golang.org/x/crypto/ssh"
-)
-
-// sshResetUPSWebUI sends a command to the UPS to restart the WebUI. This
-// command is supposed to be required to load the new cert, but that
-// doesn't seem to be true (at least it isn't on my UPS). Adding the
-// option though, in case other UPS might need it.
-func sshResetUPSWebUI(client *ssh.Client) error {
-	// make session to use for restart command
-	session, err := client.NewSession()
-	if err != nil {
-		return fmt.Errorf("ssh: restart: failed to create session (%w)", err)
-	}
-	defer session.Close()
-
-	// start shell
-	err = session.Shell()
-	if err != nil {
-		return fmt.Errorf("ssh: restart: failed to start shell (%w)", err)
-	}
-
-	// execure reboot via SendRequest
-	payload := []byte("reboot -Y")
-	payloadLen := uint8(len(payload))
-	payload = append([]byte{0, 0, 0, payloadLen}, payload...)
-
-	ok, err := session.SendRequest("exec", true, payload)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to execute scp cmd (%w)", err)
-	}
-	if !ok {
-		return errors.New("ssh: scp: execute scp cmd not ok")
-	}
-
-	// don't read remote output, as nothing interesting actually outputs
-
-	// done
-	return nil
-}
diff --git a/pkg/app/ssh_response.go b/pkg/app/ssh_response.go
deleted file mode 100644
index 8068704..0000000
--- a/pkg/app/ssh_response.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package app
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-)
-
-// sshCheckResponse reads the output from the remote and returns an error
-// if the remote output was not 0
-func sshCheckResponse(remoteOutPipe io.Reader) error {
-	buffer := make([]uint8, 1)
-	_, err := remoteOutPipe.Read(buffer)
-	if err != nil {
-		return fmt.Errorf("ssh: failed to read output buffer (%w)", err)
-	}
-
-	responseType := buffer[0]
-	message := ""
-	if responseType > 0 {
-		bufferedReader := bufio.NewReader(remoteOutPipe)
-		message, err = bufferedReader.ReadString('\n')
-		if err != nil {
-			return fmt.Errorf("ssh: failed to read output buffer (%w)", err)
-		}
-	}
-
-	// if not 0 (aka OK)
-	if responseType != 0 {
-		return fmt.Errorf("ssh: remote returned error (%d: %s)", responseType, message)
-	}
-
-	return nil
-}
diff --git a/pkg/app/ssh_scp.go b/pkg/app/ssh_scp.go
deleted file mode 100644
index 54f216c..0000000
--- a/pkg/app/ssh_scp.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package app
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"path"
-	"time"
-
-	"golang.org/x/crypto/ssh"
-)
-
-// APC UPS won't except Go's SSH "Run()" command as the format isn't quite
-// the same. Therefore, write a custom implementation to send the desired
-// command instead of relying on something like github.com/bramvdbogaerde/go-scp
-
-const (
-	sshScpP15Destination    = "/ssl/defaultcert.p15"
-	sshScpP15PermissionsStr = "0600"
-
-	sshScpTimeout = 90 * time.Second
-)
-
-// sshScpSendFileToUPS sends the p15File to the APC UPS via the SCP protocol. it is
-// automatically placed in the correct directory and will overwrite any existing
-// file
-func sshScpSendFileToUPS(client *ssh.Client, p15File []byte) error {
-	// make session to use for SCP
-	session, err := client.NewSession()
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to create session (%w)", err)
-	}
-	defer session.Close()
-
-	// attach pipes
-	out, err := session.StdoutPipe()
-	if err != nil {
-		return err
-	}
-	w, err := session.StdinPipe()
-	if err != nil {
-		return err
-	}
-	defer w.Close()
-
-	// send execute cmd --
-	// build cmd to send as request
-	// Go implementation sends additional 0x22 bytes when using Run() (as
-	// compared to putty's scp tool). these additional bytes seem to cause the
-	// apc ups to fail execution of the command
-	payload := []byte(fmt.Sprintf("scp -q -t %s", sshScpP15Destination))
-	payloadLen := uint8(len(payload))
-	payload = append([]byte{0, 0, 0, payloadLen}, payload...)
-
-	ok, err := session.SendRequest("exec", true, payload)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to execute scp cmd (%w)", err)
-	}
-	if !ok {
-		return errors.New("ssh: scp: execute scp cmd not ok")
-	}
-
-	// check remote response
-	// Note: File upload may not work if the client doesn't actually read from
-	// the remote output.
-	err = sshCheckResponse(out)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send scp cmd (bad remote response) (%w)", err)
-	}
-
-	// just file name (without path)
-	filename := path.Base(sshScpP15Destination)
-
-	// send file header
-	_, err = fmt.Fprintln(w, "C"+sshScpP15PermissionsStr, len(p15File), filename)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send file info (%w)", err)
-	}
-
-	err = sshCheckResponse(out)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send file info (bad remote response) (%w)", err)
-	}
-
-	// send actual file
-	_, err = io.Copy(w, bytes.NewReader(p15File))
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send file(%w)", err)
-	}
-
-	// send file end
-	_, err = fmt.Fprint(w, "\x00")
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send final 00 byte (%w)", err)
-	}
-
-	err = sshCheckResponse(out)
-	if err != nil {
-		return fmt.Errorf("ssh: scp: failed to send file (bad remote response) (%w)", err)
-	}
-
-	// done
-	return nil
-}

From dda11df624f31d50b61c3762e5098cb9479d0d15 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:12 -0400
Subject: [PATCH 11/54] install: add support for native ssl command The code
 should auto-select the native ssl method if the ssl command is available on
 the UPS.

If this fails, install will drop back to the original install method used by this tool (which works on NMC2).
---
 pkg/apcssh/shell.go    |  5 ++-
 pkg/apcssh/ssl.go      | 74 ++++++++++++++++++++++++++++++++++++++----
 pkg/app/cmd_create.go  |  2 +-
 pkg/app/cmd_install.go |  4 +--
 pkg/app/pem_to_p15.go  |  6 ++--
 5 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/pkg/apcssh/shell.go b/pkg/apcssh/shell.go
index c6f082c..4643621 100644
--- a/pkg/apcssh/shell.go
+++ b/pkg/apcssh/shell.go
@@ -79,7 +79,10 @@ func (cli *Client) cmd(command string) (*upsCmdResponse, error) {
 			codeTxtIndx := strings.Index(result, "\n")
 			res.codeText = result[:codeTxtIndx-1]
 
-			res.resultText = result[codeTxtIndx+1 : len(result)-2]
+			// avoid out of bounds if no result text
+			if codeTxtIndx+1 <= len(result)-2 {
+				res.resultText = result[codeTxtIndx+1 : len(result)-2]
+			}
 			break
 		}
 	}
diff --git a/pkg/apcssh/ssl.go b/pkg/apcssh/ssl.go
index 514545d..c3fac28 100644
--- a/pkg/apcssh/ssl.go
+++ b/pkg/apcssh/ssl.go
@@ -1,14 +1,74 @@
 package apcssh
 
-import "fmt"
+import (
+	"fmt"
+	"strings"
+)
 
-// InstallSSLCert installs the specified p15 cert file on the UPS. This
-// function currently only works on NMC2.
-func (cli *Client) InstallSSLCert(keyCertP15 []byte) error {
-	// install NMC2 P15 file
-	err := cli.UploadSCP("/ssl/defaultcert.p15", keyCertP15, 0600)
+// InstallSSLCert installs the specified p15 key and p15 cert files on the
+// UPS. It has logic to deduce if the NMC is a newer version (e.g., NMC3 with
+// newer firmware) and acts accordingly.
+func (cli *Client) InstallSSLCert(keyP15 []byte, certPem []byte, keyCertP15 []byte) error {
+	// run `ssl` command to check if it exists
+	result, err := cli.cmd("ssl")
 	if err != nil {
-		return fmt.Errorf("apcssh: ssl cert install: failed to send file to ups over scp (%w)", err)
+		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cmd (%w)", err)
+	}
+	// E101 is the code for "Command Not Found"
+	supportsSSLCmd := strings.ToLower(result.code) != "e101"
+
+	// if SSL is supported, use that method
+	if supportsSSLCmd {
+		return cli.installSSLCertModern(keyP15, certPem)
+	}
+
+	// fallback to legacy
+	return cli.installSSLCertLegacy(keyCertP15)
+}
+
+// installSSLCertModern installs the SSL key and certificate using the UPS built-in
+// command `ssl`. This command is not present on older devices (e.g., NMC2) or firmwares.
+func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
+	// upload the key P15 file
+	err := cli.UploadSCP("/ssl/nmc.key", keyP15, 0600)
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send nmc.key file to ups over scp (%w)", err)
+	}
+
+	// upload the cert PEM file
+	err = cli.UploadSCP("/ssl/nmc.crt", certPem, 0666)
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send nmc.key file to ups over scp (%w)", err)
+	}
+
+	// run `ssl` install commands
+	result, err := cli.cmd("ssl key -i /ssl/nmc.key")
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl key install cmd (%w)", err)
+	}
+	if strings.ToLower(result.code) != "e000" {
+		return fmt.Errorf("apcssh: ssl cert install: ssl key install cmd returned error code (%s: %s)", result.code, result.codeText)
+	}
+
+	result, err = cli.cmd("ssl cert -i /ssl/nmc.crt")
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cert install cmd (%w)", err)
+	}
+	if strings.ToLower(result.code) != "e000" {
+		return fmt.Errorf("apcssh: ssl cert install: ssl cert install cmd returned error code (%s: %s)", result.code, result.codeText)
+	}
+
+	return nil
+}
+
+// installSSLCertLegacy installs the SSL key and certificate by directly uploading
+// them to a .p15 file on the UPS. This is used for older devices (e.g., NMC2) and
+// firmwares that do not support the `ssl` command.
+func (cli *Client) installSSLCertLegacy(keyCertP15 []byte) error {
+	// upload/install keyCert P15 file
+	err := cli.UploadSCP("/ssl/defaultcert.p15", keyCertP15, 0600)
+	if err != nil {
+		return fmt.Errorf("apcssh: ssl cert install: failed to send defaultcert.p15 file to ups over scp (%w)", err)
 	}
 
 	return nil
diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index c5d700c..de9512d 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -31,7 +31,7 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	// validation done
 
 	// make p15 files
-	apcKeyCertFile, keyFile, err := app.pemToAPCP15s(keyPem, certPem, "create")
+	keyFile, apcKeyCertFile, err := app.pemToAPCP15(keyPem, certPem, "create")
 	if err != nil {
 		return err
 	}
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index f59bd7b..f4b8a22 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -46,7 +46,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	// validation done
 
 	// make p15 file
-	keyCertP15, _, err := app.pemToAPCP15s(keyPem, certPem, "install")
+	keyP15, keyCertP15, err := app.pemToAPCP15(keyPem, certPem, "install")
 	if err != nil {
 		return err
 	}
@@ -66,7 +66,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	}
 
 	// install SSL Cert
-	err = client.InstallSSLCert(keyCertP15)
+	err = client.InstallSSLCert(keyP15, certPem, keyCertP15)
 	if err != nil {
 		return fmt.Errorf("install: failed to send file to ups over scp (%w)", err)
 	}
diff --git a/pkg/app/pem_to_p15.go b/pkg/app/pem_to_p15.go
index b006c9e..e376bc6 100644
--- a/pkg/app/pem_to_p15.go
+++ b/pkg/app/pem_to_p15.go
@@ -5,10 +5,10 @@ import (
 	"fmt"
 )
 
-// pemToAPCP15s reads the specified pem files and returns the apc p15 files (both a
+// pemToAPCP15 reads the specified pem files and returns the apc p15 files (both a
 // p15 file with just the private key, and also a p15 file with both the private key
 // and certificate). The key+cert file includes the required APC header, prepended.
-func (app *app) pemToAPCP15s(keyPem, certPem []byte, parentCmdName string) (apcKeyCertFile, keyFile []byte, err error) {
+func (app *app) pemToAPCP15(keyPem, certPem []byte, parentCmdName string) (keyFile []byte, apcKeyCertFile []byte, err error) {
 	app.stdLogger.Printf("%s: making apc p15 file from pem", parentCmdName)
 
 	// make p15 struct
@@ -36,5 +36,5 @@ func (app *app) pemToAPCP15s(keyPem, certPem []byte, parentCmdName string) (apcK
 
 	app.stdLogger.Printf("%s: apc p15 file data succesfully generated", parentCmdName)
 
-	return apcKeyCertFile, keyFile, nil
+	return keyFile, apcKeyCertFile, nil
 }

From ce9958e42275b35bac267ee0bdc84d93fd8d486f Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:13 -0400
Subject: [PATCH 12/54] create: always produce both p15 files

---
 pkg/app/cmd_create.go | 32 +++++++++++++-------------------
 pkg/app/config.go     |  2 --
 2 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index de9512d..1a6c88a 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -48,6 +48,12 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	}
 
 	// write file(s)
+	err = os.WriteFile(keyFileName, keyFile, 0600)
+	if err != nil {
+		return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
+	}
+	app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
+
 	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0600)
 	if err != nil {
 		return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
@@ -57,6 +63,13 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	// if debug, write additional debug files (b64 format to make copy/paste into asn1 decoder
 	// easy to do e.g., https://lapo.it/asn1js)
 	if app.config.debugLogging != nil && *app.config.debugLogging {
+		keyFileNameDebug := keyFileName + ".b64"
+		err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0600)
+		if err != nil {
+			return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
+		}
+		app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
+
 		keyCertFileNameDebug := keyCertFileName + ".noheader.b64"
 		err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
 		if err != nil {
@@ -73,24 +86,5 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 
 	}
 
-	// make key p15 ?
-	if app.config.create.makeKeyP15 != nil && *app.config.create.makeKeyP15 {
-		err = os.WriteFile(keyFileName, keyFile, 0600)
-		if err != nil {
-			return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
-		}
-		app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
-
-		// debug file ?
-		if app.config.debugLogging != nil && *app.config.debugLogging {
-			keyFileNameDebug := keyFileName + ".b64"
-			err = os.WriteFile(keyFileNameDebug, []byte(base64.StdEncoding.EncodeToString(keyFile)), 0600)
-			if err != nil {
-				return fmt.Errorf("create: failed to write apc p15 key file (%s)", err)
-			}
-			app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
-		}
-	}
-
 	return nil
 }
diff --git a/pkg/app/config.go b/pkg/app/config.go
index a3b18c1..e8ff1fc 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -29,7 +29,6 @@ type config struct {
 	create       struct {
 		keyCertPemCfg
 		outFilePath    *string
-		makeKeyP15     *bool
 		outKeyFilePath *string
 	}
 	install struct {
@@ -74,7 +73,6 @@ func (app *app) getConfig(args []string) error {
 	cfg.create.keyPem = createFlags.StringLong("keypem", "", "string of the rsa-1024 or rsa-2048 key in pem format")
 	cfg.create.certPem = createFlags.StringLong("certpem", "", "string of the certificate in pem format")
 	cfg.create.outFilePath = createFlags.StringLong("outfile", createDefaultOutFilePath, "path and filename to write the key+cert p15 file to")
-	cfg.create.makeKeyP15 = createFlags.BoolLong("keyp15", "create a second p15 file with just the private key")
 	cfg.create.outKeyFilePath = createFlags.StringLong("outkeyfile", createDefaultOutKeyFilePath, "path and filename to write the key p15 file to")
 
 	createCmd := &ff.Command{

From 12c613f3b4371d7975b65049dc5b5db054ae32e0 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:13 -0400
Subject: [PATCH 13/54] apcssh: remove logging For sanity and consistency,
 centralize logging in the app with the app's loggers.

---
 pkg/apcssh/client.go   | 8 +-------
 pkg/app/cmd_install.go | 5 +++++
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/pkg/apcssh/client.go b/pkg/apcssh/client.go
index 33b01d5..4e7f1d3 100644
--- a/pkg/apcssh/client.go
+++ b/pkg/apcssh/client.go
@@ -4,9 +4,7 @@ import (
 	"crypto/sha256"
 	"encoding/base64"
 	"encoding/hex"
-	"errors"
 	"fmt"
-	"log"
 	"net"
 	"runtime"
 	"strings"
@@ -57,10 +55,7 @@ func New(cfg *Config) (*Client, error) {
 
 		// check for fingerprint match (b64 or hex)
 		if actualHashB64 != cfg.ServerFingerprint && actualHashHex != cfg.ServerFingerprint {
-			log.Printf("apcssh: remote server key fingerprint (b64): %s", actualHashB64)
-			log.Printf("apcssh: remote server key fingerprint (hex): %s", actualHashHex)
-
-			return errors.New("apcssh: fingerprint didn't match")
+			return fmt.Errorf("apcssh: server returned wrong fingerprint (b64: %s ; hex: %s)", actualHashB64, actualHashHex)
 		}
 
 		return nil
@@ -86,7 +81,6 @@ func New(cfg *Config) (*Client, error) {
 
 	// insecure cipher options?
 	if cfg.InsecureCipher {
-		log.Println("WARNING: insecure ciphers are enabled (--insecurecipher). SSH with an insecure cipher is NOT secure and should NOT be used.")
 		ciphers = append(ciphers, "aes128-cbc", "3des-cbc")
 	}
 
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index f4b8a22..3cdf2cf 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -51,6 +51,11 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 		return err
 	}
 
+	// log warning if insecure cipher
+	if app.config.install.insecureCipher != nil && *app.config.install.insecureCipher {
+		app.stdLogger.Println("WARNING: install: insecure ciphers are enabled (--insecurecipher). SSH with an insecure cipher is NOT secure and should NOT be used.")
+	}
+
 	// make APC SSH client
 	cfg := &apcssh.Config{
 		Hostname:          *app.config.install.hostAndPort,

From 579419ae31ce264bfb470f3aa8894516fdca8c3e Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:13 -0400
Subject: [PATCH 14/54] cmd: remove cmd done log msgs remove these unncessary
 log messages because it says done before any returned error (which could
 imply it didn't error)

---
 pkg/app/cmd_create.go  | 3 ---
 pkg/app/cmd_install.go | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index 1a6c88a..77f13ee 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -15,9 +15,6 @@ const (
 // cmdCreate is the app's command to create an apc p15 file from key and cert
 // pem files
 func (app *app) cmdCreate(_ context.Context, args []string) error {
-	// done
-	defer app.stdLogger.Println("create: done")
-
 	// extra args == error
 	if len(args) != 0 {
 		return fmt.Errorf("create: failed, %w (%d)", ErrExtraArgs, len(args))
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index 3cdf2cf..fa310b7 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -10,9 +10,6 @@ import (
 // cmdInstall is the app's command to create apc p15 file content from key and cert
 // pem files and upload the p15 to the specified APC UPS
 func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
-	// done
-	defer app.stdLogger.Println("install: done")
-
 	// extra args == error
 	if len(args) != 0 {
 		return fmt.Errorf("install: failed, %w (%d)", ErrExtraArgs, len(args))

From 67503e663672f786573462f5b02c2566dba5b9de Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:13 -0400
Subject: [PATCH 15/54] v0.5.0-preview2

---
 CHANGELOG.md | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1963c3..7217ba9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,27 +1,39 @@
 # APC P15 Tool Changelog
 
-## [v0.5.0] - 2024-06-04
+## [v0.5.0] - 2024-06-06
 
-Add functionality to additionally output a key.p15 file. This file
-format matches that of APC's NMC Security Wizard's key file output.
-(Use `create` and flag `--keyp15`.)
+-- Preview Build 2 --
+
+Add additional output of a key.p15 file. This file format matches 
+that of APC's NMC Security Wizard's key file output.
+
+Add functionality to `install` command to leverage the native `ssl`
+command if the UPS device supports it. This should be applicable
+to newer devices such as NMC3 on newer firmwares. The tool auto
+selects the correct install method. Note: There may still be some
+devices that don't work with the install function. I can only test
+the one piece of hardware I have. If you have issues, try updating
+your device's firmware first.
 
 Add creation of additional base64 encoded files when the `--debug`
 flag is used with `create`. This makes it easier to paste these
 encoded files into an ASN1 viewer to analyze them.
 
-Modify output file permissions to `0666` instead of `0777`.
+Modify output file permissions to `0600` instead of `0777`.
 
 Update Go version to 1.22.3.
 
+
 ## [v0.4.2] - 2024-03-29
 
 Fix usage message. Thanks @k725.
 
+
 ## [v0.4.1] - 2024-03-06
 
 Update to Go 1.22.1, which includes some security fixes.
 
+
 ## [v0.4.0] - 2024-02-05
 
 Add `--restartwebui` flag to issue a reboot command to the webui
@@ -29,6 +41,7 @@ after a new certificate is installed. This was not needed with
 my NMC2, but I suspect some might need it to get the new certificate
 to actually load.
 
+
 ## [v0.3.3] - 2024-02-04
 
 Add `--insecurecipher` flag to enable aes128-cbc and 3des-cbc for
@@ -36,6 +49,7 @@ older devices/firmwares. These ciphers are considered insecure and
 should be avoided. A better alternative is to update the device
 firmware if possible.
 
+
 ## [v0.3.2] - 2024-02-04
 
 Add support for 1,024 bit RSA keys. These are not recommended! RSA
@@ -45,11 +59,13 @@ Add `diffie-hellman-group-exchange-sha256` key exchange algorithm
 which may be needed by some UPSes to connect via SSH to use the
 install command.
 
+
 ## [v0.3.1] - 2024-02-03
 
 Fixes debug logging always being on. App now accurately reflects
 the state of the --debug flag.
 
+
 ## [v0.3.0] - 2024-02-03
 
 Initial release.

From a47dd3fb68a28962a3ffcc17c674882295b06052 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Thu, 6 Jun 2024 22:51:14 -0400
Subject: [PATCH 16/54] go: update to 1.22.4

---
 go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index 2ae4f6a..ad1bc05 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.22.3
+go 1.22.4
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From c669621bd3f275a864fb7f7444697d837d1016d3 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:38 -0400
Subject: [PATCH 17/54] install: add ssh connect log message

---
 pkg/app/cmd_install.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index fa310b7..b02d112 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -66,6 +66,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	if err != nil {
 		return fmt.Errorf("install: failed to connect to host (%w)", err)
 	}
+	app.stdLogger.Println("install: connected to ups ssh, installing ssl key and cert...")
 
 	// install SSL Cert
 	err = client.InstallSSLCert(keyP15, certPem, keyCertP15)

From 7bf70c4d7152f5e20ffa89698e90570a9d23023f Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:39 -0400
Subject: [PATCH 18/54] ssh: switch string comps to EqualFold func

---
 pkg/apcssh/cmd_restartwebui.go | 2 +-
 pkg/apcssh/ssl.go              | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pkg/apcssh/cmd_restartwebui.go b/pkg/apcssh/cmd_restartwebui.go
index 4b904c1..bde8d3a 100644
--- a/pkg/apcssh/cmd_restartwebui.go
+++ b/pkg/apcssh/cmd_restartwebui.go
@@ -16,7 +16,7 @@ func (cli *Client) RestartWebUI() error {
 		return err
 	}
 
-	if strings.ToLower(result.code) != "e000" {
+	if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: failed to restart web ui (%s: %s)", result.code, result.codeText)
 	}
 
diff --git a/pkg/apcssh/ssl.go b/pkg/apcssh/ssl.go
index c3fac28..233ea38 100644
--- a/pkg/apcssh/ssl.go
+++ b/pkg/apcssh/ssl.go
@@ -15,7 +15,7 @@ func (cli *Client) InstallSSLCert(keyP15 []byte, certPem []byte, keyCertP15 []by
 		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cmd (%w)", err)
 	}
 	// E101 is the code for "Command Not Found"
-	supportsSSLCmd := strings.ToLower(result.code) != "e101"
+	supportsSSLCmd := !strings.EqualFold(result.code, "e101")
 
 	// if SSL is supported, use that method
 	if supportsSSLCmd {
@@ -46,7 +46,7 @@ func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
 	if err != nil {
 		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl key install cmd (%w)", err)
 	}
-	if strings.ToLower(result.code) != "e000" {
+	if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: ssl cert install: ssl key install cmd returned error code (%s: %s)", result.code, result.codeText)
 	}
 
@@ -54,7 +54,7 @@ func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
 	if err != nil {
 		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cert install cmd (%w)", err)
 	}
-	if strings.ToLower(result.code) != "e000" {
+	if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: ssl cert install: ssl cert install cmd returned error code (%s: %s)", result.code, result.codeText)
 	}
 

From 208827f6360e7874f84355524af37c06f064e7b6 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:40 -0400
Subject: [PATCH 19/54] ssh: fix shell regex * from ssh videos I found on
 youtube, the @ symbol might not be present in prompt, so make it optional *
 fix typo of 0-0 instead of 0-9 (all numbers are possible in the prompt)

---
 pkg/apcssh/shell_helpers.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pkg/apcssh/shell_helpers.go b/pkg/apcssh/shell_helpers.go
index e2084cb..7c36c60 100644
--- a/pkg/apcssh/shell_helpers.go
+++ b/pkg/apcssh/shell_helpers.go
@@ -11,8 +11,8 @@ func scanAPCShell(data []byte, atEOF bool) (advance int, token []byte, err error
 		return 0, nil, nil
 	}
 
-	// regex for shell prompt (e.g., `apc@apc>`)
-	re := regexp.MustCompile(`(\r\n|\r|\n)[A-Za-z0-0.]+@[A-Za-z0-0.]+>`)
+	// regex for shell prompt (e.g., `apc@apc>`, `apc>`, `some@dev>`, `other123>`, etc.)
+	re := regexp.MustCompile(`(\r\n|\r|\n)([A-Za-z0-9.]+@?)?[A-Za-z0-9.]+>`)
 
 	// find match for prompt
 	if index := re.FindStringIndex(string(data)); index != nil {

From b94e17e8f33e499989f021a976960111e372c192 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:41 -0400
Subject: [PATCH 20/54] readme: update info regarding insecure ssh ciphers

---
 README.md | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 119a724..fb1cae5 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,12 @@ setup) is:
 If you have problems you can post the log in an issue and I can try to fix it
 but it may be difficult without your particular hardware to test with.
 
-In particular, if you are experiencing `ssh: handshake failed:` please run 
-`ssh -vv myups.example.com` and include the `peer server KEXINIT proposal`
-in your issue. For example:
+In particular, if you are experiencing `ssh: handshake failed:` first try
+using the `--insecurecipher` flag. If this works, you should upgrade your
+NMC to a newer firmware which includes secure ciphers. You should NOT automate
+your environment using this flag as SSH over these ciphers is broken and
+exploitable. If this also does not work, please run `ssh -vv myups.example.com`
+and include the `peer server KEXINIT proposal` in your issue. For example:
 
 ```
 debug2: peer server KEXINIT proposal

From d3ad01da0c2f3b6483bf86cb0bbf777844e96104 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:42 -0400
Subject: [PATCH 21/54] build: fix typo for windows install only file

---
 build.ps1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.ps1 b/build.ps1
index 3fee1f4..7147a33 100644
--- a/build.ps1
+++ b/build.ps1
@@ -11,7 +11,7 @@ go build -o $outDir/apc-p15-tool-amd64.exe ./cmd/tool
 $env:GOARCH = "amd64"
 $env:GOOS = "windows"
 $env:CGO_ENABLED = 0
-go build -o $outDir/apc-p15-install-amd64.exe ./cmd/tool
+go build -o $outDir/apc-p15-install-amd64.exe ./cmd/install_only
 
 # Linux x64
 $env:GOARCH = "amd64"

From 04307eff17a9722a4f2f11da2a2bfe919fcf3e58 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:30:43 -0400
Subject: [PATCH 22/54] readme: update general info about tool and
 compatibility

---
 README.md | 91 ++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index fb1cae5..b41e8f3 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,78 @@
 # APC P15 Tool
-A tool to create APC p15 formatted certificates from pem files, without
-having to use APC's closed-source tool, APC generated keys, or other 
-proprietary tools (such as cryptlib).
+
+APC P15 Tool is a completely open source application designed to make 
+creating and installing SSL certificates on APC (Schneider Electric) 
+Network Management Cards (2 & 3) simple and easy to do. It is also 
+designed to simplify automation of the certificate management lifecycle.
+
+## Background
+
+When APC created the NMC2 (Network Management Card 2), they chose to use 
+the p15 file format for their SSL keys and certificates, which is a 
+relatively obscure file format. In addition to this, they designed the
+device to require an APC specific header be prepended to the p15 file
+or the file would be rejected by the device. Accordingly, they created 
+a proprietary tool (the `NMC Security Wizard CLI Utility`) to generate
+the required format.
+
+Unfortunately, the proprietary tool has a number of shortcomings:
+- It can be difficult to find the right version to use. APC has released
+  a number of versions (in both a CLI and GUI form). Not all of the
+  versions worked correctly (or at all).
+- User provided private keys are not supported. Private keys must be 
+  generated by the proprietary tool and are only outputted in the p15 
+  format. APC's proprietary tool is closed source and as such there is 
+  no way to audit the key generation process.
+- Since the generated keys are in the p15 format, they can't be loaded
+  easily into other management tools (such as Cert Warden
+  https://www.certwarden.com/), nor can CSRs be generated easily 
+  outside of the proprietary tool. The proprietary tool is generally
+  required to generate the CSR.
+- The CSR generation function in the proprietary tool is fairly rigid,
+  making customization (e.g., multiple DNS names) difficult, if not 
+  impossible.
+- After the user generates a key, generates a CSR, sends that CSR to 
+  their CA, and receives a certificate back, they're still not done.
+  The tool must be used again to generate the final p15 file for the
+  NMC.
+- To install the final file on the NMC, the user must use an SCP
+  program such as `pscp` to install the file, or the NMC's web UI.
+
+Due to all of this, others have tried to recreate the proprietary
+functionality. The only implementations I have found rely on a closed
+source library called `cryptlib`. This library has evolved over time
+and more recent versions do not work for the NMC (it appears at some
+point cryptlib switched from 3DES to AES and NMC does not support
+AES within the p15 file). It was also near impossible to find an old
+enough version of cryptlib that would work. Even if one gets this 
+working, it does not resolve the obscurity of a closed source 
+implementation and would continue to be subject to potential future
+breakage as the cryptlib library continues to evolve.
+
+This project aims to solve all of these problems by accepting the most
+common key and cert file format (PEM) and by being 100% open source
+and licensed under the GPL-3.0 license.
 
 ## Compatibility Notice
 
-This tool's create functionality is modeled from the APC NMCSecurityWizardCLI 
-aka `NMC Security Wizard CLI Utility`. The files it generates should be 
-comaptible with any UPS that accepts p15 files from that tool. Only RSA 1,024
-and 2,048 bit keys are accepted. 1,024 bit RSA is no longer considered 
-completely secure; avoid keys of this size if possible. Most (all?) public 
-ACME services won't accept keys of this size anyway.
+Both NMC2 and NMC3 devices should be fully supported. However, I have one
+NMC2 device in a home lab and have no way to guarantee success in all cases.
 
-The install functionality is a custom creation of mine so it may or may not 
-work depending on your exact setup. My setup (and therefore the testing 
-setup) is:
+Only RSA 1,024 and 2,048 bit keys are accepted. 1,024 bit RSA is no longer 
+considered completely secure; avoid keys of this size if possible. Most 
+(all?) public ACME services won't accept keys of this size anyway.
+
+Even though later versions of the NMC3 firmware supports RSA 4,096 and 
+ECDSA keys, this tool does not. These options were not available in APC's
+proprietary tool, and as such I have no way to generate files to reverse 
+engineer.
+
+My setup (and therefore the testing setup) is:
 - APC Smart-UPS 1500VA RM 2U SUA1500RM2U (Firmware Revision 667.18.D)
 - AP9631 NMC2 Hardware Revision 05 running AOS v7.0.4 and Boot Monitor 
   v1.0.9.
 
-If you have problems you can post the log in an issue and I can try to fix it
+If you have problems, please post the log in an issue and I can try to fix it
 but it may be difficult without your particular hardware to test with.
 
 In particular, if you are experiencing `ssh: handshake failed:` first try
@@ -62,14 +115,16 @@ content.
 
 e.g. `./apc-p15-tool create --keyfile ./apckey.pem --certfile ./apccert.pem`
 
-The command outputs ./apctool.p15 by default. This file can be 
-directly loaded on to an APC NMC2 (Network Management Card 2).
+The command creates and outputs ./apctool.p15 and ./apctool.key.p15 by
+default. These files are equivelant to the key and final p15 files
+generated by APC's proprietary tool.
 
 ### Install
 
-Install works similarly to create except it doesn't save the p15 file 
-to disk. It instead uploads the p15 file directly to the specified 
-remote host, via scp.
+Install generates the necessary p15 file(s) but does NOT save them to
+disk. It instead installs the files directly on the NMC. Logic
+automatically deduces if the device is an NMC2 or NMC3 and performs
+the appropriate installation steps.
 
 e.g. `./apc-p15-tool install --keyfile ./apckey.pem --certfile ./apccert.pem --apchost myapc.example.com:22 --username apc --password someSecret --fingerprint 123abc`
 

From f1dd079632d8d134948ce969f81269f255ca4b8b Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 18 Jun 2024 21:38:00 -0400
Subject: [PATCH 23/54] v0.5.1

---
 CHANGELOG.md   | 48 +++++++++++++++++++++++++++++++-----------------
 pkg/app/app.go |  2 +-
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7217ba9..b2ab32c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,27 +1,41 @@
 # APC P15 Tool Changelog
 
-## [v0.5.0] - 2024-06-06
+## [v0.5.1] - 2024-06-18
 
--- Preview Build 2 --
+Both NMC2 and NMC3 should now be fully supported.
 
-Add additional output of a key.p15 file. This file format matches 
-that of APC's NMC Security Wizard's key file output.
+### Added
+- Add proper NMC3 support. 
+- The `create` function now also generates a .p15 formatted key file.
+  The format of this file matches that of what is generated by the NMC 
+  Security Wizard.
+- Add additional b64 formatted output files when using the `--debug`
+  flag with `create`. These files can easily be pasted into an ASN1 
+  decoder for inspection (except for the header file, as the header is
+  not ASN1 encoded).
 
-Add functionality to `install` command to leverage the native `ssl`
-command if the UPS device supports it. This should be applicable
-to newer devices such as NMC3 on newer firmwares. The tool auto
-selects the correct install method. Note: There may still be some
-devices that don't work with the install function. I can only test
-the one piece of hardware I have. If you have issues, try updating
-your device's firmware first.
+### Fixed
+- Fix `install` function for NMC3 on newer firmware version by 
+  leveraging the native `ssl` command to install the key and cert, if
+  it is available. If not available, fallback to the 'old' way of
+  installing the SSL cert.
+- Fix PowerShell build script in repo. Posted builds were not impacted
+  by this as the script is not used by the GitHub Action.
 
-Add creation of additional base64 encoded files when the `--debug`
-flag is used with `create`. This makes it easier to paste these
-encoded files into an ASN1 viewer to analyze them.
+### Changed
+- Move APC SSH functions to a separate package and change how commands
+  are sent. In particular, leverage the interactive shell to send
+  commands and read back the result of those commands.
+- Set output file permissions to `0600` instead of `0777`.
+- Minor logging updates.
+- Leverage `strings.EqualFold` as a more robust alternative to using
+  `strings.ToLower` for string comparisons.
+- Update Go version to 1.22.4.
+- Update readme to clarify tool's purpose, current state, and 
+  compatibility.
 
-Modify output file permissions to `0600` instead of `0777`.
-
-Update Go version to 1.22.3.
+### Removed
+N/A
 
 
 ## [v0.4.2] - 2024-03-29
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 5cd9ebe..b02d805 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "0.5.0"
+	appVersion = "0.5.1"
 )
 
 // struct for receivers to use common app pieces

From 841a459dcad3dbc6bd9e207cbd02797a3fa290d3 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Wed, 19 Jun 2024 19:56:16 -0400
Subject: [PATCH 24/54] apcssh: minor log and logic clarity

---
 pkg/apcssh/cmd_restartwebui.go | 6 ++----
 pkg/apcssh/scp.go              | 2 +-
 pkg/apcssh/ssl.go              | 8 +++-----
 pkg/app/cmd_install.go         | 2 +-
 4 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/pkg/apcssh/cmd_restartwebui.go b/pkg/apcssh/cmd_restartwebui.go
index bde8d3a..5196212 100644
--- a/pkg/apcssh/cmd_restartwebui.go
+++ b/pkg/apcssh/cmd_restartwebui.go
@@ -13,10 +13,8 @@ import (
 func (cli *Client) RestartWebUI() error {
 	result, err := cli.cmd("reboot -Y")
 	if err != nil {
-		return err
-	}
-
-	if !strings.EqualFold(result.code, "e000") {
+		return fmt.Errorf("apcssh: failed to restart web ui (%w)", err)
+	} else if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: failed to restart web ui (%s: %s)", result.code, result.codeText)
 	}
 
diff --git a/pkg/apcssh/scp.go b/pkg/apcssh/scp.go
index 9db77c0..a37d154 100644
--- a/pkg/apcssh/scp.go
+++ b/pkg/apcssh/scp.go
@@ -19,7 +19,7 @@ func (cli *Client) UploadSCP(destination string, fileContent []byte, filePermiss
 	// connect
 	sshClient, err := ssh.Dial("tcp", cli.hostname, cli.sshCfg)
 	if err != nil {
-		return fmt.Errorf("apcssh: scp: failed to dial session (%w)", err)
+		return fmt.Errorf("apcssh: scp: failed to dial client (%w)", err)
 	}
 	defer sshClient.Close()
 
diff --git a/pkg/apcssh/ssl.go b/pkg/apcssh/ssl.go
index 233ea38..2eb3bce 100644
--- a/pkg/apcssh/ssl.go
+++ b/pkg/apcssh/ssl.go
@@ -12,7 +12,7 @@ func (cli *Client) InstallSSLCert(keyP15 []byte, certPem []byte, keyCertP15 []by
 	// run `ssl` command to check if it exists
 	result, err := cli.cmd("ssl")
 	if err != nil {
-		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cmd (%w)", err)
+		return fmt.Errorf("apcssh: ssl cert install: failed to test ssl cmd (%w)", err)
 	}
 	// E101 is the code for "Command Not Found"
 	supportsSSLCmd := !strings.EqualFold(result.code, "e101")
@@ -45,16 +45,14 @@ func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
 	result, err := cli.cmd("ssl key -i /ssl/nmc.key")
 	if err != nil {
 		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl key install cmd (%w)", err)
-	}
-	if !strings.EqualFold(result.code, "e000") {
+	} else if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: ssl cert install: ssl key install cmd returned error code (%s: %s)", result.code, result.codeText)
 	}
 
 	result, err = cli.cmd("ssl cert -i /ssl/nmc.crt")
 	if err != nil {
 		return fmt.Errorf("apcssh: ssl cert install: failed to send ssl cert install cmd (%w)", err)
-	}
-	if !strings.EqualFold(result.code, "e000") {
+	} else if !strings.EqualFold(result.code, "e000") {
 		return fmt.Errorf("apcssh: ssl cert install: ssl cert install cmd returned error code (%s: %s)", result.code, result.codeText)
 	}
 
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index b02d112..d3270a4 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -71,7 +71,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	// install SSL Cert
 	err = client.InstallSSLCert(keyP15, certPem, keyCertP15)
 	if err != nil {
-		return fmt.Errorf("install: failed to send file to ups over scp (%w)", err)
+		return fmt.Errorf("install: %w", err)
 	}
 
 	// installed

From 703c26bd271a37135198dc9583770d5338fe0045 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Wed, 19 Jun 2024 19:56:17 -0400
Subject: [PATCH 25/54] apcssh: add shell cmd timeout It was possible for
 scanner.Scan() to block indefinitely if the UPS never returned the expected
 prompt regex pattern. This could occur with a UPS using a prompt format I'm
 not aware of, or if the UPS responds in a non-standard way.

This change ensures that Scan() is aborted after a fixed amount of blocking time and the shell cmd function accordingly returns an error.

Some error messages, comments, and var names are also updated for clarity.
---
 pkg/apcssh/shell.go         | 120 +++++++++++++++++++++++++-----------
 pkg/apcssh/shell_helpers.go |  16 ++---
 2 files changed, 92 insertions(+), 44 deletions(-)

diff --git a/pkg/apcssh/shell.go b/pkg/apcssh/shell.go
index 4643621..bb05639 100644
--- a/pkg/apcssh/shell.go
+++ b/pkg/apcssh/shell.go
@@ -2,14 +2,25 @@ package apcssh
 
 import (
 	"bufio"
+	"errors"
 	"fmt"
 	"strings"
+	"time"
 
 	"golang.org/x/crypto/ssh"
 )
 
-// upsCmdResponse is a structure that holds all of a shell commands results
-type upsCmdResponse struct {
+// Abort shell connection if UPS doesn't send a recognizable response within
+// the specified timeouts; Cmd timeout is very long as it is unlikely to be
+// needed but still exists to avoid an indefinite hang in the unlikely event
+// something does go wrong at that part of the app
+const (
+	shellTimeoutLogin = 20 * time.Second
+	shellTimeoutCmd   = 5 * time.Minute
+)
+
+// upsCmdResult is a structure that holds all of a shell commands results
+type upsCmdResult struct {
 	command    string
 	code       string
 	codeText   string
@@ -17,75 +28,112 @@ type upsCmdResponse struct {
 }
 
 // cmd creates an interactive shell and executes the specified command
-func (cli *Client) cmd(command string) (*upsCmdResponse, error) {
+func (cli *Client) cmd(command string) (*upsCmdResult, error) {
 	// connect
 	sshClient, err := ssh.Dial("tcp", cli.hostname, cli.sshCfg)
 	if err != nil {
-		return nil, fmt.Errorf("apcssh: failed to dial session (%w)", err)
+		return nil, fmt.Errorf("failed to dial client (%w)", err)
 	}
 	defer sshClient.Close()
 
 	session, err := sshClient.NewSession()
 	if err != nil {
-		return nil, fmt.Errorf("apcssh: failed to create session (%w)", err)
+		return nil, fmt.Errorf("failed to create session (%w)", err)
 	}
 	defer session.Close()
 
 	// pipes to send shell command to; and to receive repsonse
 	sshInput, err := session.StdinPipe()
 	if err != nil {
-		return nil, fmt.Errorf("apcssh: failed to make shell input pipe (%w)", err)
+		return nil, fmt.Errorf("failed to make shell input pipe (%w)", err)
 	}
 	sshOutput, err := session.StdoutPipe()
 	if err != nil {
-		return nil, fmt.Errorf("apcssh: failed to make shell output pipe (%w)", err)
+		return nil, fmt.Errorf("failed to make shell output pipe (%w)", err)
 	}
 
-	// make scanner to read shell continuously
+	// make scanner to read shell output continuously
 	scanner := bufio.NewScanner(sshOutput)
 	scanner.Split(scanAPCShell)
 
 	// start interactive shell
 	if err := session.Shell(); err != nil {
-		return nil, fmt.Errorf("apcssh: failed to start shell (%w)", err)
+		return nil, fmt.Errorf("failed to start shell (%w)", err)
 	}
-	// discard the initial shell response (login message(s) / initial shell prompt)
-	for {
-		if token := scanner.Scan(); token {
-			_ = scanner.Bytes()
-			break
+
+	// use a timer to close the session early in case Scan() hangs (which can
+	// happen if the UPS provides output this app does not understand)
+	cancelAbort := make(chan struct{})
+	defer close(cancelAbort)
+	go func() {
+		select {
+		case <-time.After(shellTimeoutLogin):
+			_ = session.Close()
+
+		case <-cancelAbort:
+			// aborted cancel (i.e., succesful Scan())
 		}
+	}()
+
+	// check shell response after connect
+	scannedOk := scanner.Scan()
+	// if failed to scan (e.g., timer closed the session after timeout)
+	if !scannedOk {
+		return nil, errors.New("shell did not return parsable login response")
 	}
+	// success; cancel abort timer
+	cancelAbort <- struct{}{}
+	// discard the initial shell response (login message(s) / initial shell prompt)
+	_ = scanner.Bytes()
 
 	// send command
 	_, err = fmt.Fprint(sshInput, command+"\n")
 	if err != nil {
-		return nil, fmt.Errorf("apcssh: failed to send shell command (%w)", err)
+		return nil, fmt.Errorf("failed to send shell command (%w)", err)
 	}
 
-	res := &upsCmdResponse{}
-	for {
-		if tkn := scanner.Scan(); tkn {
-			result := string(scanner.Bytes())
+	// use a timer to close the session early in case Scan() hangs (which can
+	// happen if the UPS provides output this app does not understand);
+	// since initial login message Scan() was okay, it is relatively unlikely this
+	// will hang
+	go func() {
+		select {
+		case <-time.After(shellTimeoutCmd):
+			_ = session.Close()
 
-			cmdIndx := strings.Index(result, "\n")
-			res.command = result[:cmdIndx-1]
-			result = result[cmdIndx+1:]
-
-			codeIndx := strings.Index(result, ": ")
-			res.code = result[:codeIndx]
-			result = result[codeIndx+2:]
-
-			codeTxtIndx := strings.Index(result, "\n")
-			res.codeText = result[:codeTxtIndx-1]
-
-			// avoid out of bounds if no result text
-			if codeTxtIndx+1 <= len(result)-2 {
-				res.resultText = result[codeTxtIndx+1 : len(result)-2]
-			}
-			break
+		case <-cancelAbort:
+			// aborted cancel (i.e., succesful Scan())
 		}
+	}()
+
+	// check shell response to command
+	scannedOk = scanner.Scan()
+	// if failed to scan (e.g., timer closed the session after timeout)
+	if !scannedOk {
+		return nil, fmt.Errorf("shell did not return parsable response to cmd '%s'", command)
+	}
+	// success; cancel abort timer
+	cancelAbort <- struct{}{}
+
+	// parse the UPS response into result struct and return
+	upsRawResponse := string(scanner.Bytes())
+	result := &upsCmdResult{}
+
+	cmdIndx := strings.Index(upsRawResponse, "\n")
+	result.command = upsRawResponse[:cmdIndx-1]
+	upsRawResponse = upsRawResponse[cmdIndx+1:]
+
+	codeIndx := strings.Index(upsRawResponse, ": ")
+	result.code = upsRawResponse[:codeIndx]
+	upsRawResponse = upsRawResponse[codeIndx+2:]
+
+	codeTxtIndx := strings.Index(upsRawResponse, "\n")
+	result.codeText = upsRawResponse[:codeTxtIndx-1]
+
+	// avoid out of bounds if no result text
+	if codeTxtIndx+1 <= len(upsRawResponse)-2 {
+		result.resultText = upsRawResponse[codeTxtIndx+1 : len(upsRawResponse)-2]
 	}
 
-	return res, nil
+	return result, nil
 }
diff --git a/pkg/apcssh/shell_helpers.go b/pkg/apcssh/shell_helpers.go
index 7c36c60..02c5e81 100644
--- a/pkg/apcssh/shell_helpers.go
+++ b/pkg/apcssh/shell_helpers.go
@@ -1,31 +1,31 @@
 package apcssh
 
 import (
+	"io"
 	"regexp"
 )
 
 // scanAPCShell is a SplitFunc to capture shell output after each interactive
 // shell command is run
 func scanAPCShell(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	if atEOF && len(data) == 0 {
+	// EOF is not an expected response and should error (e.g., when the output pipe
+	// gets closed by timeout)
+	if atEOF {
+		return len(data), dropCR(data), io.ErrUnexpectedEOF
+	} else if len(data) == 0 {
+		// no data to process, request more data
 		return 0, nil, nil
 	}
 
 	// regex for shell prompt (e.g., `apc@apc>`, `apc>`, `some@dev>`, `other123>`, etc.)
 	re := regexp.MustCompile(`(\r\n|\r|\n)([A-Za-z0-9.]+@?)?[A-Za-z0-9.]+>`)
-
 	// find match for prompt
 	if index := re.FindStringIndex(string(data)); index != nil {
 		// advance starts after the prompt; token is everything before the prompt
 		return index[1], dropCR(data[0:index[0]]), nil
 	}
 
-	// If we're at EOF, we have a final, non-terminated line. Return it.
-	if atEOF {
-		return len(data), dropCR(data), nil
-	}
-
-	// Request more data.
+	// no match, request more data
 	return 0, nil, nil
 }
 

From b7026ff9067f450e9685fd96722a20a90087e800 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Wed, 19 Jun 2024 19:57:56 -0400
Subject: [PATCH 26/54] v0.5.2

---
 CHANGELOG.md   | 6 ++++++
 pkg/app/app.go | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b2ab32c..39c9104 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # APC P15 Tool Changelog
 
+## [v0.5.2] - 2024-06-19
+
+Minor tweak to the previous version. Add timeout for shell
+commands that don't execute as expected.
+
+
 ## [v0.5.1] - 2024-06-18
 
 Both NMC2 and NMC3 should now be fully supported.
diff --git a/pkg/app/app.go b/pkg/app/app.go
index b02d805..d1f4d6d 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "0.5.1"
+	appVersion = "0.5.2"
 )
 
 // struct for receivers to use common app pieces

From 06f9892501b9fb9c14b73fdd95a4d9ff8eae9301 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 24 Jun 2024 18:23:02 -0400
Subject: [PATCH 27/54] add rsa 3,072 bit support

---
 README.md                | 13 +++++++------
 pkg/pkcs15/pem_decode.go |  6 +++---
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index b41e8f3..541a046 100644
--- a/README.md
+++ b/README.md
@@ -58,14 +58,15 @@ and licensed under the GPL-3.0 license.
 Both NMC2 and NMC3 devices should be fully supported. However, I have one
 NMC2 device in a home lab and have no way to guarantee success in all cases.
 
-Only RSA 1,024 and 2,048 bit keys are accepted. 1,024 bit RSA is no longer 
-considered completely secure; avoid keys of this size if possible. Most 
+Only RSA 1,024, 2,048, and 3,072 bit keys are accepted. 1,024 bit RSA is no
+longer considered completely secure; avoid keys of this size if possible. Most 
 (all?) public ACME services won't accept keys of this size anyway.
 
-Even though later versions of the NMC3 firmware supports RSA 4,096 and 
-ECDSA keys, this tool does not. These options were not available in APC's
-proprietary tool, and as such I have no way to generate files to reverse 
-engineer.
+NMC2 does not officially support the 3,072 bit key size, however, it works fine
+on my NMC2. If you use this size and it doesn't work on your NMC2, try a 2,048
+bit key instead. Later versions of the NMC3 firmware support RSA 4,096 and 
+ECDSA keys, but this tool does not. ECDSA was not included in APC's proprietary
+tool, and as such I have no way to generate files to reverse engineer.
 
 My setup (and therefore the testing setup) is:
 - APC Smart-UPS 1500VA RM 2U SUA1500RM2U (Firmware Revision 667.18.D)
diff --git a/pkg/pkcs15/pem_decode.go b/pkg/pkcs15/pem_decode.go
index d4b8764..1fab7d0 100644
--- a/pkg/pkcs15/pem_decode.go
+++ b/pkg/pkcs15/pem_decode.go
@@ -13,7 +13,7 @@ var (
 	errPemKeyBadBlock       = errors.New("pkcs15: pem key: failed to decode pem block")
 	errPemKeyFailedToParse  = errors.New("pkcs15: pem key: failed to parse key")
 	errPemKeyWrongBlockType = errors.New("pkcs15: pem key: unsupported pem block type (only pkcs1 and pkcs8 supported)")
-	errPemKeyWrongType      = errors.New("pkcs15: pem key: unsupported key type (only rsa 1,024 or 2,048 supported)")
+	errPemKeyWrongType      = errors.New("pkcs15: pem key: unsupported key type (only rsa 1,024, 2,048, and 3,072 supported)")
 
 	errPemCertBadBlock      = errors.New("pkcs15: pem cert: failed to decode pem block")
 	errPemCertFailedToParse = errors.New("pkcs15: pem cert: failed to parse cert")
@@ -48,7 +48,7 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 		}
 
 		// verify proper bitlen
-		if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 {
+		if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 && rsaKey.N.BitLen() != 3072 {
 			return nil, errPemKeyWrongType
 		}
 
@@ -71,7 +71,7 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 			}
 
 			// verify proper bitlen
-			if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 {
+			if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 && rsaKey.N.BitLen() != 3072 {
 				return nil, errPemKeyWrongType
 			}
 

From 7c1ad8ef437840c387fe3bdc3e2ce97a138df529 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 24 Jun 2024 18:23:05 -0400
Subject: [PATCH 28/54] pkcs15: add some prep for maybe ec key support later

---
 pkg/pkcs15/keyid.go       | 98 +++++++++++++++++++++++++--------------
 pkg/pkcs15/pem_decode.go  | 46 +++++++++++++-----
 pkg/pkcs15/pem_parse.go   |  4 +-
 pkg/pkcs15/pem_to_p15.go  | 55 +++++++++++++---------
 pkg/pkcs15/private_key.go | 50 +++++++++++++-------
 5 files changed, 167 insertions(+), 86 deletions(-)

diff --git a/pkg/pkcs15/keyid.go b/pkg/pkcs15/keyid.go
index 76f4297..68a3051 100644
--- a/pkg/pkcs15/keyid.go
+++ b/pkg/pkcs15/keyid.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/rsa"
 	"crypto/sha1"
 	"encoding/binary"
 	"math/big"
@@ -11,22 +12,6 @@ import (
 func (p15 *pkcs15KeyCert) keyId() []byte {
 	// object to hash is just the RawSubjectPublicKeyInfo
 
-	// Create Object to hash
-	// hashObj := asn1obj.Sequence([][]byte{
-	// 	asn1obj.Sequence([][]byte{
-	// 		// Key is RSA
-	// 		asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
-	// 		asn1.NullBytes,
-	// 	}),
-	// 	// BIT STRING of rsa key public key
-	// 	asn1obj.BitString(
-	// 		asn1obj.Sequence([][]byte{
-	// 			asn1obj.Integer(p15.key.N),
-	// 			asn1obj.Integer((big.NewInt(int64(p15.key.E)))),
-	// 		}),
-	// 	),
-	// })
-
 	// SHA-1 Hash
 	hasher := sha1.New()
 	_, err := hasher.Write(p15.cert.RawSubjectPublicKeyInfo)
@@ -124,18 +109,28 @@ func (p15 *pkcs15KeyCert) keyIdInt7() []byte {
 }
 
 // keyIdInt8 returns the sequence for keyId with INT val of 8; This value is equivelant
-// to "pgp", which is PGP v3 key Id. This value is just the last 8 bytes of the public
-// key N value
+// to "pgp", which is PGP v3 key Id.
 func (p15 *pkcs15KeyCert) keyIdInt8() []byte {
-	nBytes := p15.key.N.Bytes()
+	var keyIdVal []byte
+
+	switch privKey := p15.key.(type) {
+	case *rsa.PrivateKey:
+		// RSA: The ID value is just the last 8 bytes of the public key N value
+		nBytes := privKey.N.Bytes()
+		keyIdVal = nBytes[len(nBytes)-8:]
+
+	default:
+		// panic if non-RSA key
+		panic("key id 8 for non-rsa key is unexpected and unsupported")
+	}
 
 	// object to return
-	obj := asn1obj.Sequence([][]byte{
+	idObj := asn1obj.Sequence([][]byte{
 		asn1obj.Integer(big.NewInt(8)),
-		asn1obj.OctetString(nBytes[len(nBytes)-8:]),
+		asn1obj.OctetString(keyIdVal),
 	})
 
-	return obj
+	return idObj
 }
 
 // bigIntToMpi returns the MPI (as defined in RFC 4880 s 3.2) from a given
@@ -156,33 +151,64 @@ func (p15 *pkcs15KeyCert) keyIdInt9() []byte {
 	// Public-Key packet starting with the version field.  The Key ID is the
 	// low-order 64 bits of the fingerprint.
 
-	// the entire Public-Key packet
+	// first make the public key packet
 	publicKeyPacket := []byte{}
 
 	// starting with the version field (A one-octet version number (4)).
 	publicKeyPacket = append(publicKeyPacket, byte(4))
 
 	// A four-octet number denoting the time that the key was created.
-	time := make([]byte, 4)
-
 	// NOTE: use cert validity start as proxy for key creation since key pem
 	// doesn't actually contain a created at time -- in reality notBefore tends
 	// to be ~ 1 hour ish BEFORE the cert was even created. Key would also
 	// obviously have to be created prior to the cert creation.
+	time := make([]byte, 4)
 	binary.BigEndian.PutUint32(time, uint32(p15.cert.NotBefore.Unix()))
 	publicKeyPacket = append(publicKeyPacket, time...)
 
-	// A one-octet number denoting the public-key algorithm of this key.
-	// 1 - RSA (Encrypt or Sign) [HAC]
-	publicKeyPacket = append(publicKeyPacket, byte(1))
+	// the next part is key type specific
+	switch privKey := p15.key.(type) {
+	case *rsa.PrivateKey:
+		// A one-octet number denoting the public-key algorithm of this key.
+		// 1 - RSA (Encrypt or Sign) [HAC]
+		publicKeyPacket = append(publicKeyPacket, byte(1))
 
-	// Algorithm-Specific Fields for RSA public keys:
-	// multiprecision integer (MPI) of RSA public modulus n
-	publicKeyPacket = append(publicKeyPacket, bigIntToMpi(p15.key.N)...)
+		// Algorithm-Specific Fields for RSA public keys:
+		// multiprecision integer (MPI) of RSA public modulus n
+		publicKeyPacket = append(publicKeyPacket, bigIntToMpi(privKey.N)...)
 
-	// MPI of RSA public encryption exponent e
-	e := big.NewInt(int64(p15.key.PublicKey.E))
-	publicKeyPacket = append(publicKeyPacket, bigIntToMpi(e)...)
+		// MPI of RSA public encryption exponent e
+		e := big.NewInt(int64(privKey.PublicKey.E))
+		publicKeyPacket = append(publicKeyPacket, bigIntToMpi(e)...)
+
+	// case *ecdsa.PrivateKey:
+	// 	// A one-octet number denoting the public-key algorithm of this key.
+	// 	// 19 - ECDSA public key algorithm (see rfc 6637 s. 5)
+	// 	publicKeyPacket = append(publicKeyPacket, uint8(19))
+
+	// 	// Algorithm-Specific Fields for ECDSA public keys (see rfc 6637 s. 11 table)
+	// 	// This is a length byte followed by the curve ID (length is the number of bytes the curve ID uses)
+	// 	switch privKey.Curve.Params().Name {
+	// 	case "P-256":
+	// 		// 1.2.840.10045.3.1.7    8   2A 86 48 CE 3D 03 01 07   NIST curve P-256
+	// 		publicKeyPacket = append(publicKeyPacket, byte(8))
+	// 		hex, _ := hex.DecodeString("2A8648CE3D030107")
+	// 		publicKeyPacket = append(publicKeyPacket, hex...)
+
+	// 	case "P-384":
+	// 		// 1.3.132.0.34           5   2B 81 04 00 22            NIST curve P-384
+	// 		publicKeyPacket = append(publicKeyPacket, byte(5))
+	// 		hex, _ := hex.DecodeString("2B81040022")
+	// 		publicKeyPacket = append(publicKeyPacket, hex...)
+
+	// 	default:
+	// 		panic(fmt.Sprintf("key id 9 for ecdsa key curve %s is unexpected and unsupported", privKey.Curve.Params().Name))
+	// 	}
+
+	default:
+		// panic if non-RSA key
+		panic("key id 9 for non-rsa key is unexpected and unsupported")
+	}
 
 	// Assemble the V4 byte array that will be hashed
 	// 0x99 (1 octet)
@@ -205,10 +231,10 @@ func (p15 *pkcs15KeyCert) keyIdInt9() []byte {
 	keyId := sha1Hash[len(sha1Hash)-8:]
 
 	// object to return
-	obj := asn1obj.Sequence([][]byte{
+	idObj := asn1obj.Sequence([][]byte{
 		asn1obj.Integer(big.NewInt(9)),
 		asn1obj.OctetString(keyId),
 	})
 
-	return obj
+	return idObj
 }
diff --git a/pkg/pkcs15/pem_decode.go b/pkg/pkcs15/pem_decode.go
index 1fab7d0..66a34b7 100644
--- a/pkg/pkcs15/pem_decode.go
+++ b/pkg/pkcs15/pem_decode.go
@@ -1,12 +1,14 @@
 package pkcs15
 
 import (
+	"crypto"
 	"crypto/rsa"
 	"crypto/tls"
 	"crypto/x509"
 	"encoding/pem"
 	"errors"
 	"fmt"
+	"reflect"
 )
 
 var (
@@ -22,7 +24,7 @@ var (
 // pemKeyDecode attempts to decode a pem encoded byte slice and then attempts
 // to parse an RSA private key from the decoded pem block. an error is returned
 // if any of these steps fail OR if the key is not RSA and of bitlen 1,024 or 2,048
-func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
+func pemKeyDecode(keyPem []byte) (crypto.PrivateKey, error) {
 	// decode
 	pemBlock, _ := pem.Decode([]byte(keyPem))
 	if pemBlock == nil {
@@ -30,13 +32,11 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 	}
 
 	// parsing depends on block type
-	var rsaKey *rsa.PrivateKey
+	var privateKey crypto.PrivateKey
 
 	switch pemBlock.Type {
 	case "RSA PRIVATE KEY": // PKCS1
-		var err error
-
-		rsaKey, err = x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
+		rsaKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
 		if err != nil {
 			return nil, errPemKeyFailedToParse
 		}
@@ -53,6 +53,22 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 		}
 
 		// good to go
+		privateKey = rsaKey
+
+	// case "EC PRIVATE KEY": // SEC1, ASN.1
+	// 	var ecdKey *ecdsa.PrivateKey
+	// 	ecdKey, err := x509.ParseECPrivateKey(pemBlock.Bytes)
+	// 	if err != nil {
+	// 		return nil, errPemKeyFailedToParse
+	// 	}
+
+	// 	// verify acceptable curve name
+	// 	if ecdKey.Curve.Params().Name != "P-256" && ecdKey.Curve.Params().Name != "P-384" {
+	// 		return nil, errPemKeyWrongType
+	// 	}
+
+	// 	// good to go
+	// 	privateKey = ecdKey
 
 	case "PRIVATE KEY": // PKCS8
 		pkcs8Key, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes)
@@ -62,20 +78,28 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 
 		switch pkcs8Key := pkcs8Key.(type) {
 		case *rsa.PrivateKey:
-			rsaKey = pkcs8Key
-
 			// basic sanity check
-			err = rsaKey.Validate()
+			err = pkcs8Key.Validate()
 			if err != nil {
 				return nil, fmt.Errorf("pkcs15: pem key: failed sanity check (%s)", err)
 			}
 
 			// verify proper bitlen
-			if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 && rsaKey.N.BitLen() != 3072 {
+			if pkcs8Key.N.BitLen() != 1024 && pkcs8Key.N.BitLen() != 2048 && pkcs8Key.N.BitLen() != 3072 {
 				return nil, errPemKeyWrongType
 			}
 
 			// good to go
+			privateKey = pkcs8Key
+
+		// case *ecdsa.PrivateKey:
+		// 	// verify acceptable curve name
+		// 	if pkcs8Key.Curve.Params().Name != "P-256" && pkcs8Key.Curve.Params().Name != "P-384" {
+		// 		return nil, errPemKeyWrongType
+		// 	}
+
+		// 	// good to go
+		// 	privateKey = pkcs8Key
 
 		default:
 			return nil, errPemKeyWrongType
@@ -86,12 +110,12 @@ func pemKeyDecode(keyPem []byte) (*rsa.PrivateKey, error) {
 	}
 
 	// if rsaKey is nil somehow, error
-	if rsaKey == nil {
+	if reflect.ValueOf(privateKey).IsNil() {
 		return nil, errors.New("pkcs15: pem key: rsa key unexpectedly nil (report bug to project repo)")
 	}
 
 	// success!
-	return rsaKey, nil
+	return privateKey, nil
 }
 
 // pemCertDecode attempts to decode a pem encoded byte slice and then attempts
diff --git a/pkg/pkcs15/pem_parse.go b/pkg/pkcs15/pem_parse.go
index dcd899a..2cd1fea 100644
--- a/pkg/pkcs15/pem_parse.go
+++ b/pkg/pkcs15/pem_parse.go
@@ -1,14 +1,14 @@
 package pkcs15
 
 import (
-	"crypto/rsa"
+	"crypto"
 	"crypto/x509"
 )
 
 // pkcs15KeyCert holds the data for a key and certificate pair; it provides
 // various methods to transform pkcs15 data
 type pkcs15KeyCert struct {
-	key  *rsa.PrivateKey
+	key  crypto.PrivateKey
 	cert *x509.Certificate
 }
 
diff --git a/pkg/pkcs15/pem_to_p15.go b/pkg/pkcs15/pem_to_p15.go
index 19392f2..c213ddb 100644
--- a/pkg/pkcs15/pem_to_p15.go
+++ b/pkg/pkcs15/pem_to_p15.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/rsa"
 	"encoding/asn1"
 	"math/big"
 )
@@ -111,6 +112,38 @@ func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err
 // the APC tool uses when generating a new private key (Note: no header is used on
 // this file)
 func (p15 *pkcs15KeyCert) toP15Key(keyEnvelope []byte) (key []byte, err error) {
+	// create public key object
+	var pubKeyObj []byte
+
+	switch privKey := p15.key.(type) {
+	case *rsa.PrivateKey:
+		pubKeyObj = asn1obj.ExplicitCompound(1, [][]byte{
+			asn1obj.Sequence([][]byte{
+				asn1obj.ExplicitCompound(0, [][]byte{
+					asn1obj.ExplicitCompound(1, [][]byte{
+						asn1obj.Sequence([][]byte{
+							asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
+							asn1.NullBytes,
+						}),
+						// RSAPublicKey SubjectPublicKeyInfo
+						asn1obj.BitString(
+							asn1obj.Sequence([][]byte{
+								asn1obj.Integer(privKey.PublicKey.N),
+								asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.E))),
+							}),
+						),
+					}),
+				}),
+				// not 100% certain but appears to be rsa key byte len
+				asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.N.BitLen() / 8))),
+			}),
+		})
+
+	default:
+		// panic if non-RSA key
+		panic("p15 key file for non-rsa key is unexpected and unsupported")
+	}
+
 	// private key object (slightly different than the key+cert format)
 	privateKey := asn1obj.Sequence([][]byte{
 		// commonObjectAttributes - Label
@@ -181,27 +214,7 @@ func (p15 *pkcs15KeyCert) toP15Key(keyEnvelope []byte) (key []byte, err error) {
 									asn1obj.BitString([]byte{byte(0b01000000)}),
 								}),
 
-								asn1obj.ExplicitCompound(1, [][]byte{
-									asn1obj.Sequence([][]byte{
-										asn1obj.ExplicitCompound(0, [][]byte{
-											asn1obj.ExplicitCompound(1, [][]byte{
-												asn1obj.Sequence([][]byte{
-													asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
-													asn1.NullBytes,
-												}),
-												// RSAPublicKey SubjectPublicKeyInfo
-												asn1obj.BitString(
-													asn1obj.Sequence([][]byte{
-														asn1obj.Integer(p15.key.PublicKey.N),
-														asn1obj.Integer(big.NewInt(int64(p15.key.PublicKey.E))),
-													}),
-												),
-											}),
-										}),
-										// not 100% certain but appears to be rsa key byte len
-										asn1obj.Integer(big.NewInt(int64(p15.key.PublicKey.N.BitLen() / 8))),
-									}),
-								}),
+								pubKeyObj,
 							}),
 						}),
 					}),
diff --git a/pkg/pkcs15/private_key.go b/pkg/pkcs15/private_key.go
index 8c6b0fb..0321551 100644
--- a/pkg/pkcs15/private_key.go
+++ b/pkg/pkcs15/private_key.go
@@ -1,24 +1,42 @@
 package pkcs15
 
-import "apc-p15-tool/pkg/tools/asn1obj"
+import (
+	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/rsa"
+)
 
 // privateKeyObject returns the ASN.1 representation of a private key
 func (p15 *pkcs15KeyCert) privateKeyObject() []byte {
-	// ensure all expected vals are available
-	p15.key.Precompute()
+	var privKeyObj []byte
 
-	pkey := asn1obj.Sequence([][]byte{
-		// P
-		asn1obj.IntegerExplicitValue(3, p15.key.Primes[0]),
-		// Q
-		asn1obj.IntegerExplicitValue(4, p15.key.Primes[1]),
-		// Dp
-		asn1obj.IntegerExplicitValue(5, p15.key.Precomputed.Dp),
-		// Dq
-		asn1obj.IntegerExplicitValue(6, p15.key.Precomputed.Dq),
-		// Qinv
-		asn1obj.IntegerExplicitValue(7, p15.key.Precomputed.Qinv),
-	})
+	switch privKey := p15.key.(type) {
+	case *rsa.PrivateKey:
+		privKey.Precompute()
 
-	return pkey
+		// ensure all expected vals are available
+		privKeyObj = asn1obj.Sequence([][]byte{
+			// P
+			asn1obj.IntegerExplicitValue(3, privKey.Primes[0]),
+			// Q
+			asn1obj.IntegerExplicitValue(4, privKey.Primes[1]),
+			// Dp
+			asn1obj.IntegerExplicitValue(5, privKey.Precomputed.Dp),
+			// Dq
+			asn1obj.IntegerExplicitValue(6, privKey.Precomputed.Dq),
+			// Qinv
+			asn1obj.IntegerExplicitValue(7, privKey.Precomputed.Qinv),
+		})
+
+	// case *ecdsa.PrivateKey:
+	// 	// Only private piece is the integer D
+	// 	privKeyObj = asn1obj.Sequence([][]byte{
+	// 		asn1obj.Integer(privKey.D),
+	// 	})
+
+	default:
+		// panic if non-RSA key
+		panic("private key object for non-rsa key is unexpected and unsupported")
+	}
+
+	return privKeyObj
 }

From 6363282a756e259b4ffcbfabbbfe02ad3a4f4080 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 24 Jun 2024 18:24:35 -0400
Subject: [PATCH 29/54] v0.5.3

---
 CHANGELOG.md   | 5 +++++
 pkg/app/app.go | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 39c9104..f205de6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # APC P15 Tool Changelog
 
+## [v0.5.3] - 2024-06-24
+
+Add 3,072 bit RSA key support.
+
+
 ## [v0.5.2] - 2024-06-19
 
 Minor tweak to the previous version. Add timeout for shell
diff --git a/pkg/app/app.go b/pkg/app/app.go
index d1f4d6d..c228b20 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "0.5.2"
+	appVersion = "0.5.3"
 )
 
 // struct for receivers to use common app pieces

From 371a2ecc30b5c1a90777bd89b9b686fd39f8e73e Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Wed, 26 Jun 2024 21:34:47 -0400
Subject: [PATCH 30/54] README: update testing setup

Update firmware on my UPS,
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 541a046..5e47692 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ tool, and as such I have no way to generate files to reverse engineer.
 
 My setup (and therefore the testing setup) is:
 - APC Smart-UPS 1500VA RM 2U SUA1500RM2U (Firmware Revision 667.18.D)
-- AP9631 NMC2 Hardware Revision 05 running AOS v7.0.4 and Boot Monitor 
+- AP9631 NMC2 Hardware Revision 05 running AOS v7.1.2 and Boot Monitor 
   v1.0.9.
 
 If you have problems, please post the log in an issue and I can try to fix it

From 9578fa26ce358ae7b663fbc7a440bb8008d9b684 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 1 Jul 2024 22:35:21 -0400
Subject: [PATCH 31/54] fix go build ver 1.22.4

---
 .github/workflows/build_releases.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index d1a0d90..5114c97 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -8,7 +8,7 @@ on:
 
 env:
   GITHUB_REF: ${{ github.ref }}
-  GO_VERSION: '1.22.1'
+  GO_VERSION: '1.22.4'
 
 jobs:
   build-common:

From b8e9a2338651d4c5878a1957dbdbe9a965330631 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 1 Jul 2024 22:35:26 -0400
Subject: [PATCH 32/54] v1.0.0

---
 CHANGELOG.md   | 7 +++++++
 pkg/app/app.go | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f205de6..5e9c752 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # APC P15 Tool Changelog
 
+## [v1.0.0] - 2024-07-01
+
+First official stable release.
+
+Fixes Go version in Github action.
+
+
 ## [v0.5.3] - 2024-06-24
 
 Add 3,072 bit RSA key support.
diff --git a/pkg/app/app.go b/pkg/app/app.go
index c228b20..d2d9767 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "0.5.3"
+	appVersion = "1.0.0"
 )
 
 // struct for receivers to use common app pieces

From e2b5abc6249da55cae12b47ee332a4cefeb8c4f6 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 9 Jul 2024 19:16:59 -0400
Subject: [PATCH 33/54] readme: add beta notice

---
 README.md | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/README.md b/README.md
index 5e47692..42b8b30 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,14 @@ creating and installing SSL certificates on APC (Schneider Electric)
 Network Management Cards (2 & 3) simple and easy to do. It is also 
 designed to simplify automation of the certificate management lifecycle.
 
+## Help Needed from NMC3 Users!
+
+If you have an NMC3, please test the beta release (1.1.0-b). In particular,
+please provide feedback if 4,092 bit RSA keys and EC keys of curve types
+P-256, P-384, and P-521 work using the beta and your NMC3.
+
+see: https://github.com/gregtwallace/apc-p15-tool/issues/6
+
 ## Background
 
 When APC created the NMC2 (Network Management Card 2), they chose to use 

From 51e584740931de5d6b3c312c3cca0362bdc98d08 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:44:33 -0400
Subject: [PATCH 34/54] go: update to 1.23.1

---
 .github/workflows/build_releases.yml | 2 +-
 go.mod                               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 5114c97..5ff7f19 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -8,7 +8,7 @@ on:
 
 env:
   GITHUB_REF: ${{ github.ref }}
-  GO_VERSION: '1.22.4'
+  GO_VERSION: '1.23.1'
 
 jobs:
   build-common:
diff --git a/go.mod b/go.mod
index ad1bc05..11730be 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.22.4
+go 1.23.1
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From cbb831e0092942d074f7f1b66486a135654b202f Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:44:33 -0400
Subject: [PATCH 35/54] add ecdsa key support and enable 4,092 RSA * apcssh:
 add descriptive error when required file(s) not passed * create: dont create
 key+cert file when key isn't supported by NMC2 * config: fix usage messages
 re: key types * p15 files: dont generate key+cert when it isn't needed (aka
 NMC2 doesn't support key) * pkcs15: pre-calculate envelope when making the
 p15 struct * pkcs15: omit key ID 8 & 9 from EC keys * pkcs15: update key
 decode logic * pkcs15: add key type value for easy determination of
 compatibility * pkcs15: add ec key support * pkcs15: separate functions for
 key and key+cert p15 files * update README see:
 https://github.com/gregtwallace/apc-p15-tool/issues/6

---
 README.md                        |  33 ++-
 pkg/apcssh/ssl.go                |  13 +
 pkg/app/cmd_create.go            |  36 +--
 pkg/app/config.go                |   8 +-
 pkg/app/pem_to_p15.go            |  57 +++--
 pkg/pkcs15/encrypted_envelope.go |  31 ++-
 pkg/pkcs15/keyid.go              |  39 +--
 pkg/pkcs15/pem_decode.go         |  66 ++---
 pkg/pkcs15/pem_parse.go          |  62 +++++
 pkg/pkcs15/pem_to_p15.go         | 412 ++++++++++++++++++++-----------
 pkg/pkcs15/private_key.go        |  13 +-
 pkg/tools/asn1obj/oid.go         |   4 +
 12 files changed, 508 insertions(+), 266 deletions(-)

diff --git a/README.md b/README.md
index 42b8b30..27ff526 100644
--- a/README.md
+++ b/README.md
@@ -66,23 +66,36 @@ and licensed under the GPL-3.0 license.
 Both NMC2 and NMC3 devices should be fully supported. However, I have one
 NMC2 device in a home lab and have no way to guarantee success in all cases.
 
-Only RSA 1,024, 2,048, and 3,072 bit keys are accepted. 1,024 bit RSA is no
-longer considered completely secure; avoid keys of this size if possible. Most 
-(all?) public ACME services won't accept keys of this size anyway.
+### Key Types and Sizes
 
-NMC2 does not officially support the 3,072 bit key size, however, it works fine
-on my NMC2. If you use this size and it doesn't work on your NMC2, try a 2,048
-bit key instead. Later versions of the NMC3 firmware support RSA 4,096 and 
-ECDSA keys, but this tool does not. ECDSA was not included in APC's proprietary
-tool, and as such I have no way to generate files to reverse engineer.
+NMC2:
+- RSA 1,024, 2,048, 3,072* bit lengths.
+
+NMC3:
+- RSA 1,024, 2,048, 3,072, and 4,092 bit lengths.
+- ECDSA curves P-256, P-384, and P-521. 
+
+* 3,072 bit length is not officially supported by my NMC2, but appears to work
+  fine.
+
+1,024 bit RSA is no longer considered completely secure; avoid keys of 
+this size if possible. Most (all?) public ACME services won't accept keys 
+of this size anyway.
+
+### General Troubleshooting
 
 My setup (and therefore the testing setup) is:
 - APC Smart-UPS 1500VA RM 2U SUA1500RM2U (Firmware Revision 667.18.D)
 - AP9631 NMC2 Hardware Revision 05 running AOS v7.1.2 and Boot Monitor 
   v1.0.9.
 
-If you have problems, please post the log in an issue and I can try to fix it
-but it may be difficult without your particular hardware to test with.
+If you have trouble, your first step should be to update your NMC's firmware.
+Many issues with this tool will be resolved simply by updating to the newest
+firmware.
+
+If you have a problem after that, please post the log in an issue and I can 
+try to fix it but it may be difficult without your particular hardware to 
+test with.
 
 In particular, if you are experiencing `ssh: handshake failed:` first try
 using the `--insecurecipher` flag. If this works, you should upgrade your
diff --git a/pkg/apcssh/ssl.go b/pkg/apcssh/ssl.go
index 2eb3bce..18bff70 100644
--- a/pkg/apcssh/ssl.go
+++ b/pkg/apcssh/ssl.go
@@ -1,10 +1,13 @@
 package apcssh
 
 import (
+	"errors"
 	"fmt"
 	"strings"
 )
 
+var errSSLMissingData = errors.New("apcssh: ssl cert install: cant install nil data (unsupported key/nmc version/nmc firmware combo?)")
+
 // InstallSSLCert installs the specified p15 key and p15 cert files on the
 // UPS. It has logic to deduce if the NMC is a newer version (e.g., NMC3 with
 // newer firmware) and acts accordingly.
@@ -29,6 +32,11 @@ func (cli *Client) InstallSSLCert(keyP15 []byte, certPem []byte, keyCertP15 []by
 // installSSLCertModern installs the SSL key and certificate using the UPS built-in
 // command `ssl`. This command is not present on older devices (e.g., NMC2) or firmwares.
 func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
+	// fail if required data isn't present
+	if keyP15 == nil || len(keyP15) <= 0 || certPem == nil || len(certPem) <= 0 {
+		return errSSLMissingData
+	}
+
 	// upload the key P15 file
 	err := cli.UploadSCP("/ssl/nmc.key", keyP15, 0600)
 	if err != nil {
@@ -63,6 +71,11 @@ func (cli *Client) installSSLCertModern(keyP15 []byte, certPem []byte) error {
 // them to a .p15 file on the UPS. This is used for older devices (e.g., NMC2) and
 // firmwares that do not support the `ssl` command.
 func (cli *Client) installSSLCertLegacy(keyCertP15 []byte) error {
+	// fail if required data isn't present
+	if keyCertP15 == nil || len(keyCertP15) <= 0 {
+		return errSSLMissingData
+	}
+
 	// upload/install keyCert P15 file
 	err := cli.UploadSCP("/ssl/defaultcert.p15", keyCertP15, 0600)
 	if err != nil {
diff --git a/pkg/app/cmd_create.go b/pkg/app/cmd_create.go
index 77f13ee..8791a81 100644
--- a/pkg/app/cmd_create.go
+++ b/pkg/app/cmd_create.go
@@ -51,11 +51,14 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 	}
 	app.stdLogger.Printf("create: apc p15 key file %s written to disk", keyFileName)
 
-	err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0600)
-	if err != nil {
-		return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+	// skip key+cert if it wasn't generated
+	if len(apcKeyCertFile) > 0 {
+		err = os.WriteFile(keyCertFileName, apcKeyCertFile, 0600)
+		if err != nil {
+			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+		}
+		app.stdLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileName)
 	}
-	app.stdLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileName)
 
 	// if debug, write additional debug files (b64 format to make copy/paste into asn1 decoder
 	// easy to do e.g., https://lapo.it/asn1js)
@@ -67,19 +70,22 @@ func (app *app) cmdCreate(_ context.Context, args []string) error {
 		}
 		app.debugLogger.Printf("create: apc p15 key file %s written to disk", keyFileNameDebug)
 
-		keyCertFileNameDebug := keyCertFileName + ".noheader.b64"
-		err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
-		if err != nil {
-			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
-		}
-		app.debugLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileNameDebug)
+		// skip key+cert if it wasn't generated
+		if len(apcKeyCertFile) > 0 {
+			keyCertFileNameDebug := keyCertFileName + ".noheader.b64"
+			err = os.WriteFile(keyCertFileNameDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[apcHeaderLen:])), 0600)
+			if err != nil {
+				return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+			}
+			app.debugLogger.Printf("create: apc p15 key+cert file %s written to disk", keyCertFileNameDebug)
 
-		keyCertFileNameHeaderDebug := keyCertFileName + ".header.b64"
-		err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[:apcHeaderLen])), 0600)
-		if err != nil {
-			return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+			keyCertFileNameHeaderDebug := keyCertFileName + ".header.b64"
+			err = os.WriteFile(keyCertFileNameHeaderDebug, []byte(base64.StdEncoding.EncodeToString(apcKeyCertFile[:apcHeaderLen])), 0600)
+			if err != nil {
+				return fmt.Errorf("create: failed to write apc p15 key+cert file (%s)", err)
+			}
+			app.debugLogger.Printf("create: apc p15 key+cert file header %s written to disk", keyCertFileNameHeaderDebug)
 		}
-		app.debugLogger.Printf("create: apc p15 key+cert file header %s written to disk", keyCertFileNameHeaderDebug)
 
 	}
 
diff --git a/pkg/app/config.go b/pkg/app/config.go
index e8ff1fc..6ef840b 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -68,9 +68,9 @@ func (app *app) getConfig(args []string) error {
 	// create -- subcommand
 	createFlags := ff.NewFlagSet("create").SetParent(rootFlags)
 
-	cfg.create.keyPemFilePath = createFlags.StringLong("keyfile", "", "path and filename of the rsa-1024 or rsa-2048 key in pem format")
+	cfg.create.keyPemFilePath = createFlags.StringLong("keyfile", "", "path and filename of the key in pem format")
 	cfg.create.certPemFilePath = createFlags.StringLong("certfile", "", "path and filename of the certificate in pem format")
-	cfg.create.keyPem = createFlags.StringLong("keypem", "", "string of the rsa-1024 or rsa-2048 key in pem format")
+	cfg.create.keyPem = createFlags.StringLong("keypem", "", "string of the key in pem format")
 	cfg.create.certPem = createFlags.StringLong("certpem", "", "string of the certificate in pem format")
 	cfg.create.outFilePath = createFlags.StringLong("outfile", createDefaultOutFilePath, "path and filename to write the key+cert p15 file to")
 	cfg.create.outKeyFilePath = createFlags.StringLong("outkeyfile", createDefaultOutKeyFilePath, "path and filename to write the key p15 file to")
@@ -88,9 +88,9 @@ func (app *app) getConfig(args []string) error {
 	// install -- subcommand
 	installFlags := ff.NewFlagSet("install").SetParent(rootFlags)
 
-	cfg.install.keyPemFilePath = installFlags.StringLong("keyfile", "", "path and filename of the rsa-1024 or rsa-2048 key in pem format")
+	cfg.install.keyPemFilePath = installFlags.StringLong("keyfile", "", "path and filename of the key in pem format")
 	cfg.install.certPemFilePath = installFlags.StringLong("certfile", "", "path and filename of the certificate in pem format")
-	cfg.install.keyPem = installFlags.StringLong("keypem", "", "string of the rsa-1024 or rsa-2048 key in pem format")
+	cfg.install.keyPem = installFlags.StringLong("keypem", "", "string of the key in pem format")
 	cfg.install.certPem = installFlags.StringLong("certpem", "", "string of the certificate in pem format")
 	cfg.install.hostAndPort = installFlags.StringLong("apchost", "", "hostname:port of the apc ups to install the certificate on")
 	cfg.install.fingerprint = installFlags.StringLong("fingerprint", "", "the SHA256 fingerprint value of the ups' ssh server")
diff --git a/pkg/app/pem_to_p15.go b/pkg/app/pem_to_p15.go
index e376bc6..d48d4a8 100644
--- a/pkg/app/pem_to_p15.go
+++ b/pkg/app/pem_to_p15.go
@@ -3,13 +3,22 @@ package app
 import (
 	"apc-p15-tool/pkg/pkcs15"
 	"fmt"
+	"slices"
 )
 
-// pemToAPCP15 reads the specified pem files and returns the apc p15 files (both a
-// p15 file with just the private key, and also a p15 file with both the private key
-// and certificate). The key+cert file includes the required APC header, prepended.
+// list of keys supported by the NMC2
+var nmc2SupportedKeyTypes = []pkcs15.KeyType{
+	pkcs15.KeyTypeRSA1024,
+	pkcs15.KeyTypeRSA2048,
+	pkcs15.KeyTypeRSA3072, // officially not supported but works
+}
+
+// pemToAPCP15 reads the specified pem files and returns the apc p15 file(s). If the
+// key type of the key is not supported by NMC2, the combined key+cert file is not
+// generated and nil is returned instead for that file. If the key IS supported by
+// NMC2, the key+cert file is generated and the proper header is prepended.
 func (app *app) pemToAPCP15(keyPem, certPem []byte, parentCmdName string) (keyFile []byte, apcKeyCertFile []byte, err error) {
-	app.stdLogger.Printf("%s: making apc p15 file from pem", parentCmdName)
+	app.stdLogger.Printf("%s: making apc p15 file(s) content from pem", parentCmdName)
 
 	// make p15 struct
 	p15, err := pkcs15.ParsePEMToPKCS15(keyPem, certPem)
@@ -17,24 +26,40 @@ func (app *app) pemToAPCP15(keyPem, certPem []byte, parentCmdName string) (keyFi
 		return nil, nil, fmt.Errorf("%s: failed to parse pem files (%w)", parentCmdName, err)
 	}
 
-	app.stdLogger.Printf("%s: successfully loaded pem files", parentCmdName)
+	app.stdLogger.Printf("%s: successfully parsed pem files", parentCmdName)
 
-	// make file bytes
-	keyCertFile, keyFile, err := p15.ToP15Files()
+	// make key file (always)
+	keyFile, err = p15.ToP15Key()
 	if err != nil {
-		return nil, nil, fmt.Errorf("%s: failed to make p15 file (%w)", parentCmdName, err)
+		return nil, nil, fmt.Errorf("%s: failed to make p15 key file (%w)", parentCmdName, err)
 	}
 
-	// make header for file bytes
-	apcHeader, err := makeFileHeader(keyCertFile)
-	if err != nil {
-		return nil, nil, fmt.Errorf("%s: failed to make p15 file header (%w)", parentCmdName, err)
+	app.stdLogger.Printf("%s: successfully generated p15 key file content", parentCmdName)
+
+	// check key type for compat with NMC2
+	if slices.Contains(nmc2SupportedKeyTypes, p15.KeyType()) {
+		app.stdLogger.Printf("%s: key type is supported by NMC2, generating p15 key+cert file content...", parentCmdName)
+
+		// make file bytes
+		keyCertFile, err := p15.ToP15KeyCert()
+		if err != nil {
+			return nil, nil, fmt.Errorf("%s: failed to make p15 key+cert file content (%w)", parentCmdName, err)
+		}
+
+		// make header for file bytes
+		apcHeader, err := makeFileHeader(keyCertFile)
+		if err != nil {
+			return nil, nil, fmt.Errorf("%s: failed to make p15 key+cert file header (%w)", parentCmdName, err)
+		}
+
+		// combine header with file
+		apcKeyCertFile = append(apcHeader, keyCertFile...)
+	} else {
+		// NMC2 unsupported
+		app.stdLogger.Printf("%s: key type is not supported by NMC2, skipping p15 key+cert file content", parentCmdName)
 	}
 
-	// combine header with file
-	apcKeyCertFile = append(apcHeader, keyCertFile...)
-
-	app.stdLogger.Printf("%s: apc p15 file data succesfully generated", parentCmdName)
+	app.stdLogger.Printf("%s: apc p15 file(s) data succesfully generated", parentCmdName)
 
 	return keyFile, apcKeyCertFile, nil
 }
diff --git a/pkg/pkcs15/encrypted_envelope.go b/pkg/pkcs15/encrypted_envelope.go
index cead3c8..71433d1 100644
--- a/pkg/pkcs15/encrypted_envelope.go
+++ b/pkg/pkcs15/encrypted_envelope.go
@@ -21,14 +21,19 @@ const (
 	apcKEKIterations = 5000
 )
 
-// encryptedKeyEnvelope encrypts p15's rsa private key using the algorithms and
-// params expected in the APC file. Salt values are always random.
-func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
+// encryptedKeyEnvelope encrypts p15's private key using the algorithms and
+// params expected in the APC file.
+func (p15 *pkcs15KeyCert) computeEncryptedKeyEnvelope() error {
+	// if computation already performed, this is a no-op (keep existing envelope)
+	if p15.envelopedPrivateKey != nil && len(p15.envelopedPrivateKey) != 0 {
+		return nil
+	}
+
 	// calculate values for the object
 	kekSalt := make([]byte, 8)
 	_, err := rand.Read(kekSalt)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	// kek hash alg
@@ -42,7 +47,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	// make DES cipher from KEK for CEK
 	cekDesCipher, err := des.NewTripleDESCipher(kek)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	// cek (16 bytes for authEnc128) -- see: rfc3211
@@ -50,7 +55,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	cek := make([]byte, cekLen)
 	_, err = rand.Read(cek)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	// LEN + Check Val [3]
@@ -71,7 +76,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	cekPadding := make([]byte, cekPadLen)
 	_, err = rand.Read(cekPadding)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	wrappedCEK = append(wrappedCEK, cekPadding...)
@@ -80,7 +85,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	cekEncryptSalt := make([]byte, 8)
 	_, err = rand.Read(cekEncryptSalt)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	cekEncrypter := cipher.NewCBCEncrypter(cekDesCipher, cekEncryptSalt)
@@ -94,13 +99,13 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	contentEncSalt := make([]byte, 8)
 	_, err = rand.Read(contentEncSalt)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	contentEncryptKey := pbkdf2.Key(cek, []byte("encryption"), 1, 24, sha1.New)
 	contentDesCipher, err := des.NewTripleDESCipher(contentEncryptKey)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	// envelope content (that will be encrypted)
@@ -151,7 +156,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 	// make MAC
 	_, err = macHasher.Write(hashMe)
 	if err != nil {
-		return nil, err
+		return err
 	}
 	mac := macHasher.Sum(nil)
 
@@ -218,5 +223,7 @@ func (p15 *pkcs15KeyCert) encryptedKeyEnvelope() ([]byte, error) {
 		finalEnv = append(finalEnv, envelope[i]...)
 	}
 
-	return finalEnv, nil
+	// set p15 struct envelope
+	p15.envelopedPrivateKey = finalEnv
+	return nil
 }
diff --git a/pkg/pkcs15/keyid.go b/pkg/pkcs15/keyid.go
index 68a3051..08a3ce4 100644
--- a/pkg/pkcs15/keyid.go
+++ b/pkg/pkcs15/keyid.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/ecdsa"
 	"crypto/rsa"
 	"crypto/sha1"
 	"encoding/binary"
@@ -119,9 +120,13 @@ func (p15 *pkcs15KeyCert) keyIdInt8() []byte {
 		nBytes := privKey.N.Bytes()
 		keyIdVal = nBytes[len(nBytes)-8:]
 
+	case *ecdsa.PrivateKey:
+		// don't use this key id, leave empty
+		return nil
+
 	default:
-		// panic if non-RSA key
-		panic("key id 8 for non-rsa key is unexpected and unsupported")
+		// panic if unexpected key type
+		panic("key id 8 for key is unexpected and unsupported")
 	}
 
 	// object to return
@@ -181,33 +186,13 @@ func (p15 *pkcs15KeyCert) keyIdInt9() []byte {
 		e := big.NewInt(int64(privKey.PublicKey.E))
 		publicKeyPacket = append(publicKeyPacket, bigIntToMpi(e)...)
 
-	// case *ecdsa.PrivateKey:
-	// 	// A one-octet number denoting the public-key algorithm of this key.
-	// 	// 19 - ECDSA public key algorithm (see rfc 6637 s. 5)
-	// 	publicKeyPacket = append(publicKeyPacket, uint8(19))
-
-	// 	// Algorithm-Specific Fields for ECDSA public keys (see rfc 6637 s. 11 table)
-	// 	// This is a length byte followed by the curve ID (length is the number of bytes the curve ID uses)
-	// 	switch privKey.Curve.Params().Name {
-	// 	case "P-256":
-	// 		// 1.2.840.10045.3.1.7    8   2A 86 48 CE 3D 03 01 07   NIST curve P-256
-	// 		publicKeyPacket = append(publicKeyPacket, byte(8))
-	// 		hex, _ := hex.DecodeString("2A8648CE3D030107")
-	// 		publicKeyPacket = append(publicKeyPacket, hex...)
-
-	// 	case "P-384":
-	// 		// 1.3.132.0.34           5   2B 81 04 00 22            NIST curve P-384
-	// 		publicKeyPacket = append(publicKeyPacket, byte(5))
-	// 		hex, _ := hex.DecodeString("2B81040022")
-	// 		publicKeyPacket = append(publicKeyPacket, hex...)
-
-	// 	default:
-	// 		panic(fmt.Sprintf("key id 9 for ecdsa key curve %s is unexpected and unsupported", privKey.Curve.Params().Name))
-	// 	}
+	case *ecdsa.PrivateKey:
+		// don't use this key id, leave empty
+		return nil
 
 	default:
-		// panic if non-RSA key
-		panic("key id 9 for non-rsa key is unexpected and unsupported")
+		// panic if unexpected key type
+		panic("key id 9 for key is unexpected and unsupported")
 	}
 
 	// Assemble the V4 byte array that will be hashed
diff --git a/pkg/pkcs15/pem_decode.go b/pkg/pkcs15/pem_decode.go
index 66a34b7..2d51837 100644
--- a/pkg/pkcs15/pem_decode.go
+++ b/pkg/pkcs15/pem_decode.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"crypto"
+	"crypto/ecdsa"
 	"crypto/rsa"
 	"crypto/tls"
 	"crypto/x509"
@@ -9,21 +10,27 @@ import (
 	"errors"
 	"fmt"
 	"reflect"
+	"slices"
 )
 
 var (
 	errPemKeyBadBlock       = errors.New("pkcs15: pem key: failed to decode pem block")
 	errPemKeyFailedToParse  = errors.New("pkcs15: pem key: failed to parse key")
-	errPemKeyWrongBlockType = errors.New("pkcs15: pem key: unsupported pem block type (only pkcs1 and pkcs8 supported)")
-	errPemKeyWrongType      = errors.New("pkcs15: pem key: unsupported key type (only rsa 1,024, 2,048, and 3,072 supported)")
+	errPemKeyWrongBlockType = errors.New("pkcs15: pem key: unsupported pem block type")
+	errKeyWrongType         = errors.New("pkcs15: pem key: unsupported key type")
 
 	errPemCertBadBlock      = errors.New("pkcs15: pem cert: failed to decode pem block")
 	errPemCertFailedToParse = errors.New("pkcs15: pem cert: failed to parse cert")
 )
 
+var (
+	supportedRSASizes    = []int{1024, 2048, 3072, 4096}
+	supportedECDSACurves = []string{"P-256", "P-384", "P-521"}
+)
+
 // pemKeyDecode attempts to decode a pem encoded byte slice and then attempts
-// to parse an RSA private key from the decoded pem block. an error is returned
-// if any of these steps fail OR if the key is not RSA and of bitlen 1,024 or 2,048
+// to parse a private key from the decoded pem block. an error is returned
+// if any of these steps fail OR if the key is not supported.
 func pemKeyDecode(keyPem []byte) (crypto.PrivateKey, error) {
 	// decode
 	pemBlock, _ := pem.Decode([]byte(keyPem))
@@ -47,28 +54,27 @@ func pemKeyDecode(keyPem []byte) (crypto.PrivateKey, error) {
 			return nil, fmt.Errorf("pkcs15: pem key: failed sanity check (%s)", err)
 		}
 
-		// verify proper bitlen
-		if rsaKey.N.BitLen() != 1024 && rsaKey.N.BitLen() != 2048 && rsaKey.N.BitLen() != 3072 {
-			return nil, errPemKeyWrongType
+		// verify supported rsa bitlen
+		if !slices.Contains(supportedRSASizes, rsaKey.N.BitLen()) {
+			return nil, errKeyWrongType
 		}
 
 		// good to go
 		privateKey = rsaKey
 
-	// case "EC PRIVATE KEY": // SEC1, ASN.1
-	// 	var ecdKey *ecdsa.PrivateKey
-	// 	ecdKey, err := x509.ParseECPrivateKey(pemBlock.Bytes)
-	// 	if err != nil {
-	// 		return nil, errPemKeyFailedToParse
-	// 	}
+	case "EC PRIVATE KEY": // SEC1, ASN.1
+		ecdKey, err := x509.ParseECPrivateKey(pemBlock.Bytes)
+		if err != nil {
+			return nil, errPemKeyFailedToParse
+		}
 
-	// 	// verify acceptable curve name
-	// 	if ecdKey.Curve.Params().Name != "P-256" && ecdKey.Curve.Params().Name != "P-384" {
-	// 		return nil, errPemKeyWrongType
-	// 	}
+		// verify supported curve name
+		if !slices.Contains(supportedECDSACurves, ecdKey.Curve.Params().Name) {
+			return nil, errKeyWrongType
+		}
 
-	// 	// good to go
-	// 	privateKey = ecdKey
+		// good to go
+		privateKey = ecdKey
 
 	case "PRIVATE KEY": // PKCS8
 		pkcs8Key, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes)
@@ -84,25 +90,25 @@ func pemKeyDecode(keyPem []byte) (crypto.PrivateKey, error) {
 				return nil, fmt.Errorf("pkcs15: pem key: failed sanity check (%s)", err)
 			}
 
-			// verify proper bitlen
-			if pkcs8Key.N.BitLen() != 1024 && pkcs8Key.N.BitLen() != 2048 && pkcs8Key.N.BitLen() != 3072 {
-				return nil, errPemKeyWrongType
+			// verify supported rsa bitlen
+			if !slices.Contains(supportedRSASizes, pkcs8Key.N.BitLen()) {
+				return nil, errKeyWrongType
 			}
 
 			// good to go
 			privateKey = pkcs8Key
 
-		// case *ecdsa.PrivateKey:
-		// 	// verify acceptable curve name
-		// 	if pkcs8Key.Curve.Params().Name != "P-256" && pkcs8Key.Curve.Params().Name != "P-384" {
-		// 		return nil, errPemKeyWrongType
-		// 	}
+		case *ecdsa.PrivateKey:
+			// verify supported curve name
+			if !slices.Contains(supportedECDSACurves, pkcs8Key.Curve.Params().Name) {
+				return nil, errKeyWrongType
+			}
 
-		// 	// good to go
-		// 	privateKey = pkcs8Key
+			// good to go
+			privateKey = pkcs8Key
 
 		default:
-			return nil, errPemKeyWrongType
+			return nil, errKeyWrongType
 		}
 
 	default:
diff --git a/pkg/pkcs15/pem_parse.go b/pkg/pkcs15/pem_parse.go
index 2cd1fea..19e44f1 100644
--- a/pkg/pkcs15/pem_parse.go
+++ b/pkg/pkcs15/pem_parse.go
@@ -2,6 +2,8 @@ package pkcs15
 
 import (
 	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
 	"crypto/x509"
 )
 
@@ -10,6 +12,59 @@ import (
 type pkcs15KeyCert struct {
 	key  crypto.PrivateKey
 	cert *x509.Certificate
+	// store the encrypted enveloped Private Key for re-use
+	envelopedPrivateKey []byte
+}
+
+// KeyType is used by consumers to check for compatibility
+type KeyType int
+
+const (
+	KeyTypeRSA1024 KeyType = iota
+	KeyTypeRSA2048
+	KeyTypeRSA3072
+	KeyTypeRSA4096
+
+	KeyTypeECP256
+	KeyTypeECP384
+	KeyTypeECP521
+
+	KeyTypeUnknown
+)
+
+// KeyType returns the private key type
+func (p15 *pkcs15KeyCert) KeyType() KeyType {
+	switch pKey := p15.key.(type) {
+	case *rsa.PrivateKey:
+		switch pKey.N.BitLen() {
+		case 1024:
+			return KeyTypeRSA1024
+		case 2048:
+			return KeyTypeRSA2048
+		case 3072:
+			return KeyTypeRSA3072
+		case 4096:
+			return KeyTypeRSA4096
+
+		default:
+		}
+
+	case *ecdsa.PrivateKey:
+		switch pKey.Curve.Params().Name {
+		case "P-256":
+			return KeyTypeECP256
+		case "P-384":
+			return KeyTypeECP384
+		case "P-521":
+			return KeyTypeECP521
+
+		default:
+		}
+
+	default:
+	}
+
+	return KeyTypeUnknown
 }
 
 // ParsePEMToPKCS15 parses the provide pem files to a pkcs15 struct; it also does some
@@ -27,10 +82,17 @@ func ParsePEMToPKCS15(keyPem, certPem []byte) (*pkcs15KeyCert, error) {
 		return nil, err
 	}
 
+	// create p15 struct
 	p15 := &pkcs15KeyCert{
 		key:  key,
 		cert: cert,
 	}
 
+	// pre-calculate encrypted envelope
+	err = p15.computeEncryptedKeyEnvelope()
+	if err != nil {
+		return nil, err
+	}
+
 	return p15, nil
 }
diff --git a/pkg/pkcs15/pem_to_p15.go b/pkg/pkcs15/pem_to_p15.go
index c213ddb..0c2214d 100644
--- a/pkg/pkcs15/pem_to_p15.go
+++ b/pkg/pkcs15/pem_to_p15.go
@@ -2,8 +2,10 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/ecdsa"
 	"crypto/rsa"
 	"encoding/asn1"
+	"fmt"
 	"math/big"
 )
 
@@ -13,39 +15,87 @@ const (
 
 // toP15KeyCert creates a P15 file with both the private key and certificate, mirroring the
 // final p15 file an APC UPS expects (though without the header)
-func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err error) {
-	// private key object
-	privateKey := asn1obj.Sequence([][]byte{
-		// commonObjectAttributes - Label
-		asn1obj.Sequence([][]byte{
-			asn1obj.UTF8String(apcKeyLabel),
-		}),
-		// CommonKeyAttributes
-		asn1obj.Sequence([][]byte{
-			// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
-			asn1obj.OctetString(p15.keyId()),
-			// CommonKeyAttributes - usage (trailing 0s will drop)
-			asn1obj.BitString([]byte{byte(0b11100010)}),
-			// CommonKeyAttributes - accessFlags (trailing 0s will drop)
-			asn1obj.BitString([]byte{byte(0b10110000)}),
-			// CommonKeyAttributes - startDate
-			asn1obj.GeneralizedTime(p15.cert.NotBefore),
-			// CommonKeyAttributes - [0] endDate
-			asn1obj.GeneralizedTimeExplicitValue(0, p15.cert.NotAfter),
-		}),
-		// ObjectValue - indirect-protected
-		asn1obj.ExplicitCompound(1, [][]byte{
+func (p15 *pkcs15KeyCert) ToP15KeyCert() (keyCert []byte, err error) {
+	// encrypted envelope is required
+	err = p15.computeEncryptedKeyEnvelope()
+	if err != nil {
+		return nil, err
+	}
+
+	// create private key object
+	var privKeyObj []byte
+
+	switch p15.key.(type) {
+	case *rsa.PrivateKey:
+		// private key object
+		privKeyObj =
 			asn1obj.Sequence([][]byte{
-				// AuthEnvelopedData Type ([4])
-				asn1obj.ExplicitCompound(4, [][]byte{
-					keyEnvelope,
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
 				}),
-			}),
-		}),
-	})
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
+					asn1obj.OctetString(p15.keyId()),
+					// CommonKeyAttributes - usage (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b11100010)}),
+					// CommonKeyAttributes - accessFlags (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b10110000)}),
+					// CommonKeyAttributes - startDate
+					asn1obj.GeneralizedTime(p15.cert.NotBefore),
+					// CommonKeyAttributes - [0] endDate
+					asn1obj.GeneralizedTimeExplicitValue(0, p15.cert.NotAfter),
+				}),
+				// ObjectValue - indirect-protected
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						// AuthEnvelopedData Type ([4])
+						asn1obj.ExplicitCompound(4, [][]byte{
+							p15.envelopedPrivateKey,
+						}),
+					}),
+				}),
+			})
+
+	case *ecdsa.PrivateKey:
+		privKeyObj =
+			asn1obj.ExplicitCompound(0, [][]byte{
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
+				}),
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
+					asn1obj.OctetString(p15.keyId()),
+					// CommonKeyAttributes - usage (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b00100010)}),
+					// CommonKeyAttributes - accessFlags (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b10110000)}),
+					// CommonKeyAttributes - startDate
+					asn1obj.GeneralizedTime(p15.cert.NotBefore),
+					// CommonKeyAttributes - [0] endDate
+					asn1obj.GeneralizedTimeExplicitValue(0, p15.cert.NotAfter),
+				}),
+				// ObjectValue - indirect-protected
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						// AuthEnvelopedData Type ([4])
+						asn1obj.ExplicitCompound(4, [][]byte{
+							p15.envelopedPrivateKey,
+						}),
+					}),
+				}),
+			})
+
+	default:
+		// bad key type
+		return nil, errKeyWrongType
+	}
 
 	// cert object
-	cert := asn1obj.Sequence([][]byte{
+	certObj := asn1obj.Sequence([][]byte{
 		// commonObjectAttributes - Label
 		asn1obj.Sequence([][]byte{
 			asn1obj.UTF8String(apcKeyLabel),
@@ -59,6 +109,7 @@ func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err
 				p15.keyIdInt3(),
 				p15.keyIdInt6(),
 				p15.keyIdInt7(),
+				// 8 & 9 will return nil for EC keys (effectively omitting them)
 				p15.keyIdInt8(),
 				p15.keyIdInt9(),
 			}),
@@ -77,7 +128,7 @@ func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err
 		}),
 	})
 
-	// build the file
+	// build the object
 
 	// ContentInfo
 	keyCert = asn1obj.Sequence([][]byte{
@@ -92,12 +143,12 @@ func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err
 				asn1obj.Sequence([][]byte{
 					asn1obj.ExplicitCompound(0, [][]byte{
 						asn1obj.ExplicitCompound(0, [][]byte{
-							privateKey,
+							privKeyObj,
 						}),
 					}),
 					asn1obj.ExplicitCompound(4, [][]byte{
 						asn1obj.ExplicitCompound(0, [][]byte{
-							cert,
+							certObj,
 						}),
 					}),
 				}),
@@ -111,141 +162,212 @@ func (p15 *pkcs15KeyCert) toP15KeyCert(keyEnvelope []byte) (keyCert []byte, err
 // toP15Key creates a P15 file with just the private key, mirroring the p15 format
 // the APC tool uses when generating a new private key (Note: no header is used on
 // this file)
-func (p15 *pkcs15KeyCert) toP15Key(keyEnvelope []byte) (key []byte, err error) {
-	// create public key object
-	var pubKeyObj []byte
+func (p15 *pkcs15KeyCert) ToP15Key() (key []byte, err error) {
+	// encrypted envelope is required
+	err = p15.computeEncryptedKeyEnvelope()
+	if err != nil {
+		return nil, err
+	}
+
+	// create private and public key objects
+	var pubKeyObj, privKeyObj []byte
 
 	switch privKey := p15.key.(type) {
 	case *rsa.PrivateKey:
-		pubKeyObj = asn1obj.ExplicitCompound(1, [][]byte{
+		// private key object (slightly different than the key+cert format)
+		privKeyObj =
 			asn1obj.Sequence([][]byte{
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
+				}),
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
+					asn1obj.OctetString(p15.keyId()),
+					// CommonKeyAttributes - usage (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b11100010)}),
+					// CommonKeyAttributes - accessFlags (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b10110000)}),
+				}),
+
+				// Key IDs
 				asn1obj.ExplicitCompound(0, [][]byte{
-					asn1obj.ExplicitCompound(1, [][]byte{
-						asn1obj.Sequence([][]byte{
-							asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
-							asn1.NullBytes,
+					asn1obj.Sequence([][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							p15.keyIdInt2(),
+							p15.keyIdInt8(),
+							p15.keyIdInt9(),
 						}),
-						// RSAPublicKey SubjectPublicKeyInfo
-						asn1obj.BitString(
-							asn1obj.Sequence([][]byte{
-								asn1obj.Integer(privKey.PublicKey.N),
-								asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.E))),
-							}),
-						),
 					}),
 				}),
-				// not 100% certain but appears to be rsa key byte len
-				asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.N.BitLen() / 8))),
-			}),
-		})
+
+				// ObjectValue - indirect-protected
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						// AuthEnvelopedData Type ([4])
+						asn1obj.ExplicitCompound(4, [][]byte{
+							p15.envelopedPrivateKey,
+						}),
+					}),
+				}),
+			})
+
+		// pub key stub
+		pubKeyObj =
+			asn1obj.Sequence([][]byte{
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
+				}),
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					asn1obj.OctetString(p15.keyId()),
+					asn1obj.BitString([]byte{byte(0b10000010)}),
+					asn1obj.BitString([]byte{byte(0b01000000)}),
+				}),
+
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							asn1obj.ExplicitCompound(1, [][]byte{
+								asn1obj.Sequence([][]byte{
+									asn1obj.ObjectIdentifier(asn1obj.OIDrsaEncryptionPKCS1),
+									asn1.NullBytes,
+								}),
+								// RSAPublicKey SubjectPublicKeyInfo
+								asn1obj.BitString(
+									asn1obj.Sequence([][]byte{
+										asn1obj.Integer(privKey.PublicKey.N),
+										asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.E))),
+									}),
+								),
+							}),
+						}),
+						// not 100% certain but appears to be rsa key byte len
+						asn1obj.Integer(big.NewInt(int64(privKey.PublicKey.N.BitLen() / 8))),
+					}),
+				}),
+			})
+
+	case *ecdsa.PrivateKey:
+		// private key object (slightly different than the key+cert format)
+		privKeyObj =
+			asn1obj.ExplicitCompound(0, [][]byte{
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
+				}),
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
+					asn1obj.OctetString(p15.keyId()),
+					// CommonKeyAttributes - usage (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b00100010)}),
+					// CommonKeyAttributes - accessFlags (trailing 0s will drop)
+					asn1obj.BitString([]byte{byte(0b10110000)}),
+				}),
+
+				// Key IDs
+				asn1obj.ExplicitCompound(0, [][]byte{
+					asn1obj.Sequence([][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							p15.keyIdInt2(),
+						}),
+					}),
+				}),
+
+				// ObjectValue - indirect-protected
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						// AuthEnvelopedData Type ([4])
+						asn1obj.ExplicitCompound(4, [][]byte{
+							p15.envelopedPrivateKey,
+						}),
+					}),
+				}),
+			})
+
+		// convert ec pub key to a form that provides a public key bytes function
+		ecdhKey, err := privKey.PublicKey.ECDH()
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse ec public key (%s)", err)
+		}
+
+		// select correct OID for curve
+		var curveOID asn1.ObjectIdentifier
+		switch privKey.Curve.Params().Name {
+		case "P-256":
+			curveOID = asn1obj.OIDprime256v1
+		case "P-384":
+			curveOID = asn1obj.OIDsecp384r1
+		case "P-521":
+			curveOID = asn1obj.OIDsecp521r1
+		default:
+			// bad curve name
+			return nil, errKeyWrongType
+		}
+
+		// pub key stub
+		pubKeyObj =
+			asn1obj.ExplicitCompound(0, [][]byte{
+				// commonObjectAttributes - Label
+				asn1obj.Sequence([][]byte{
+					asn1obj.UTF8String(apcKeyLabel),
+				}),
+				// CommonKeyAttributes
+				asn1obj.Sequence([][]byte{
+					asn1obj.OctetString(p15.keyId()),
+					asn1obj.BitString([]byte{byte(0b00000010)}),
+					asn1obj.BitString([]byte{byte(0b01000000)}),
+				}),
+
+				asn1obj.ExplicitCompound(1, [][]byte{
+					asn1obj.Sequence([][]byte{
+						asn1obj.ExplicitCompound(0, [][]byte{
+							asn1obj.Sequence([][]byte{
+								asn1obj.Sequence([][]byte{
+									asn1obj.ObjectIdentifier(asn1obj.OIDecPublicKey),
+									asn1obj.ObjectIdentifier(curveOID),
+								}),
+								asn1obj.BitString(ecdhKey.Bytes()),
+							}),
+						}),
+					}),
+				}),
+			})
 
 	default:
-		// panic if non-RSA key
-		panic("p15 key file for non-rsa key is unexpected and unsupported")
+		// bad key type
+		return nil, errKeyWrongType
 	}
 
-	// private key object (slightly different than the key+cert format)
-	privateKey := asn1obj.Sequence([][]byte{
-		// commonObjectAttributes - Label
+	// assemble complete object
+	key =
 		asn1obj.Sequence([][]byte{
-			asn1obj.UTF8String(apcKeyLabel),
-		}),
-		// CommonKeyAttributes
-		asn1obj.Sequence([][]byte{
-			// CommonKeyAttributes - iD - uses keyId that is SHA1( SubjectPublicKeyInfo SEQUENCE )
-			asn1obj.OctetString(p15.keyId()),
-			// CommonKeyAttributes - usage (trailing 0s will drop)
-			asn1obj.BitString([]byte{byte(0b11100010)}),
-			// CommonKeyAttributes - accessFlags (trailing 0s will drop)
-			asn1obj.BitString([]byte{byte(0b10110000)}),
-		}),
-
-		//
-		asn1obj.ExplicitCompound(0, [][]byte{
-			asn1obj.Sequence([][]byte{
-				asn1obj.ExplicitCompound(0, [][]byte{
-					p15.keyIdInt2(),
-					p15.keyIdInt8(),
-					p15.keyIdInt9(),
-				}),
-			}),
-		}),
-
-		// ObjectValue - indirect-protected
-		asn1obj.ExplicitCompound(1, [][]byte{
-			asn1obj.Sequence([][]byte{
-				// AuthEnvelopedData Type ([4])
-				asn1obj.ExplicitCompound(4, [][]byte{
-					keyEnvelope,
-				}),
-			}),
-		}),
-	})
-
-	// ContentInfo
-	key = asn1obj.Sequence([][]byte{
-
-		// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
-		asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
-
-		// content
-		asn1obj.ExplicitCompound(0, [][]byte{
-			asn1obj.Sequence([][]byte{
-				asn1obj.Integer(big.NewInt(0)),
+			// contentType: OID: 1.2.840.113549.1.15.3.1 pkcs15content (PKCS #15 content type)
+			asn1obj.ObjectIdentifier(asn1obj.OIDPkscs15Content),
+			// content
+			asn1obj.ExplicitCompound(0, [][]byte{
 				asn1obj.Sequence([][]byte{
-					// [0] Private Key
-					asn1obj.ExplicitCompound(0, [][]byte{
+					asn1obj.Integer(big.NewInt(0)),
+					asn1obj.Sequence([][]byte{
+						// [0] Private Keys
 						asn1obj.ExplicitCompound(0, [][]byte{
-							privateKey,
+							asn1obj.ExplicitCompound(0, [][]byte{
+								privKeyObj,
+							}),
 						}),
-					}),
-					// [1] Public Key
-					asn1obj.ExplicitCompound(1, [][]byte{
-						asn1obj.ExplicitCompound(0, [][]byte{
-							asn1obj.Sequence([][]byte{
-								// commonObjectAttributes - Label
-								asn1obj.Sequence([][]byte{
-									asn1obj.UTF8String(apcKeyLabel),
-								}),
-								// CommonKeyAttributes
-								asn1obj.Sequence([][]byte{
-									asn1obj.OctetString(p15.keyId()),
-									asn1obj.BitString([]byte{byte(0b10000010)}),
-									asn1obj.BitString([]byte{byte(0b01000000)}),
-								}),
-
+						// [1] Public Keys
+						asn1obj.ExplicitCompound(1, [][]byte{
+							asn1obj.ExplicitCompound(0, [][]byte{
 								pubKeyObj,
 							}),
 						}),
 					}),
 				}),
 			}),
-		}),
-	})
+		})
 
 	return key, nil
 }
-
-// ToP15File turns the key and cert into a properly formatted and encoded
-// p15 file
-func (p15 *pkcs15KeyCert) ToP15Files() (keyCertFile []byte, keyFile []byte, err error) {
-	// rsa encrypted key in encrypted envelope (will be shared by both output files)
-	envelope, err := p15.encryptedKeyEnvelope()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// key + cert file
-	keyCertFile, err = p15.toP15KeyCert(envelope)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// key only file
-	keyFile, err = p15.toP15Key(envelope)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	return keyCertFile, keyFile, nil
-}
diff --git a/pkg/pkcs15/private_key.go b/pkg/pkcs15/private_key.go
index 0321551..59b538e 100644
--- a/pkg/pkcs15/private_key.go
+++ b/pkg/pkcs15/private_key.go
@@ -2,6 +2,7 @@ package pkcs15
 
 import (
 	"apc-p15-tool/pkg/tools/asn1obj"
+	"crypto/ecdsa"
 	"crypto/rsa"
 )
 
@@ -27,15 +28,13 @@ func (p15 *pkcs15KeyCert) privateKeyObject() []byte {
 			asn1obj.IntegerExplicitValue(7, privKey.Precomputed.Qinv),
 		})
 
-	// case *ecdsa.PrivateKey:
-	// 	// Only private piece is the integer D
-	// 	privKeyObj = asn1obj.Sequence([][]byte{
-	// 		asn1obj.Integer(privKey.D),
-	// 	})
+	case *ecdsa.PrivateKey:
+		// Only private piece is the integer D
+		privKeyObj = asn1obj.Integer(privKey.D)
 
 	default:
-		// panic if non-RSA key
-		panic("private key object for non-rsa key is unexpected and unsupported")
+		// panic if unsupported key
+		panic("private key type is unexpected and unsupported")
 	}
 
 	return privKeyObj
diff --git a/pkg/tools/asn1obj/oid.go b/pkg/tools/asn1obj/oid.go
index 3975ded..70009c2 100644
--- a/pkg/tools/asn1obj/oid.go
+++ b/pkg/tools/asn1obj/oid.go
@@ -11,6 +11,10 @@ var (
 	OIDdesEDE3CBC         = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7}            // des-EDE3-CBC (RSADSI encryptionAlgorithm)
 	OIDpkcs7Data          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}         // data (PKCS #7)
 	OIDauthEnc128         = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 3, 15} // authEnc128 (S/MIME Algorithms)
+	OIDecPublicKey        = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}             // ecPublicKey (ANSI X9.62 public key type)
+	OIDprime256v1         = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}          //  prime256v1 (ANSI X9.62 named elliptic curve)
+	OIDsecp384r1          = asn1.ObjectIdentifier{1, 3, 132, 0, 34}                   //  secp384r1 (SECG (Certicom) named elliptic curve)
+	OIDsecp521r1          = asn1.ObjectIdentifier{1, 3, 132, 0, 35}                   //  secp521r1 (SECG (Certicom) named elliptic curve)
 )
 
 // ObjectIdentifier returns an ASN.1 OBJECT IDENTIFIER with the oidValue bytes

From c22447b0c2d5be0d956674a4d2760af0eb43c743 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:44:33 -0400
Subject: [PATCH 36/54] readme: update info re: modern key support

---
 README.md | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 27ff526..fa53ea0 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,6 @@ creating and installing SSL certificates on APC (Schneider Electric)
 Network Management Cards (2 & 3) simple and easy to do. It is also 
 designed to simplify automation of the certificate management lifecycle.
 
-## Help Needed from NMC3 Users!
-
-If you have an NMC3, please test the beta release (1.1.0-b). In particular,
-please provide feedback if 4,092 bit RSA keys and EC keys of curve types
-P-256, P-384, and P-521 work using the beta and your NMC3.
-
-see: https://github.com/gregtwallace/apc-p15-tool/issues/6
-
 ## Background
 
 When APC created the NMC2 (Network Management Card 2), they chose to use 
@@ -71,12 +63,17 @@ NMC2 device in a home lab and have no way to guarantee success in all cases.
 NMC2:
 - RSA 1,024, 2,048, 3,072* bit lengths.
 
-NMC3:
+NMC3*:
 - RSA 1,024, 2,048, 3,072, and 4,092 bit lengths.
 - ECDSA curves P-256, P-384, and P-521. 
 
 * 3,072 bit length is not officially supported by my NMC2, but appears to work
   fine.
+* The additional key types supported by NMC3 require newer firmware on the
+  device. I am unsure what the version cutoff is, but you can check support
+  by connecting to the UPS via SSH and typing `ssl`. If `Command Not Found`
+  is returned, the firmware is too old and only the key types listed under
+  NMC2 will work.
 
 1,024 bit RSA is no longer considered completely secure; avoid keys of 
 this size if possible. Most (all?) public ACME services won't accept keys 

From 1cd9916a17fef26d18143d7f661813b3933fb06f Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:44:34 -0400
Subject: [PATCH 37/54] install: add web ui cert verification * connect to the
 ups web ui after install and verify the proper certificate is being served *
 rename `apchost` flag to `hostname` * separate ports to additional flags
 (`sshport` `sslport`) with sane defaults

---
 README.md              |  2 +-
 pkg/app/cmd_install.go | 56 +++++++++++++++++++++++++++++++++++++++---
 pkg/app/config.go      | 12 ++++++---
 3 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index fa53ea0..d339961 100644
--- a/README.md
+++ b/README.md
@@ -145,7 +145,7 @@ disk. It instead installs the files directly on the NMC. Logic
 automatically deduces if the device is an NMC2 or NMC3 and performs
 the appropriate installation steps.
 
-e.g. `./apc-p15-tool install --keyfile ./apckey.pem --certfile ./apccert.pem --apchost myapc.example.com:22 --username apc --password someSecret --fingerprint 123abc`
+e.g. `./apc-p15-tool install --keyfile ./apckey.pem --certfile ./apccert.pem --hostname myapc.example.com --username apc --password someSecret --fingerprint 123abc`
 
 ## Note About Install Automation
 
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index d3270a4..a431eb8 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -2,9 +2,14 @@ package app
 
 import (
 	"apc-p15-tool/pkg/apcssh"
+	"bytes"
 	"context"
+	"crypto/tls"
+	"encoding/pem"
 	"errors"
 	"fmt"
+	"strconv"
+	"time"
 )
 
 // cmdInstall is the app's command to create apc p15 file content from key and cert
@@ -36,7 +41,9 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	}
 
 	// host to install on must be specified
-	if app.config.install.hostAndPort == nil || *app.config.install.hostAndPort == "" {
+	if app.config.install.hostname == nil || *app.config.install.hostname == "" ||
+		app.config.install.sshport == nil || *app.config.install.sshport == 0 {
+
 		return errors.New("install: failed, apc host not specified")
 	}
 
@@ -55,7 +62,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 
 	// make APC SSH client
 	cfg := &apcssh.Config{
-		Hostname:          *app.config.install.hostAndPort,
+		Hostname:          *app.config.install.hostname + ":" + strconv.Itoa(*app.config.install.sshport),
 		Username:          *app.config.install.username,
 		Password:          *app.config.install.password,
 		ServerFingerprint: *app.config.install.fingerprint,
@@ -75,7 +82,7 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	}
 
 	// installed
-	app.stdLogger.Printf("install: apc p15 file installed on %s", *app.config.install.hostAndPort)
+	app.stdLogger.Printf("install: apc p15 file installed on %s", *app.config.install.hostname)
 
 	// restart UPS webUI
 	if app.config.install.restartWebUI != nil && *app.config.install.restartWebUI {
@@ -89,5 +96,48 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 		app.stdLogger.Println("install: sent webui restart command")
 	}
 
+	// check the new certificate is installed
+	if app.config.install.skipVerify != nil && !*app.config.install.skipVerify &&
+		app.config.install.webUISSLPort != nil && *app.config.install.webUISSLPort != 0 {
+
+		app.stdLogger.Println("install: attempting to verify certificate install...")
+
+		// sleep for UPS to finish anything it might be doing
+		time.Sleep(5 * time.Second)
+
+		// if UPS web UI was restarted, sleep longer
+		if app.config.install.restartWebUI != nil && *app.config.install.restartWebUI {
+			app.stdLogger.Println("install: waiting for ups webui restart...")
+			time.Sleep(25 * time.Second)
+		}
+
+		// connect to the web UI to get the current certificate
+		conf := &tls.Config{
+			InsecureSkipVerify: true,
+		}
+		conn, err := tls.Dial("tcp", *app.config.install.hostname+":"+strconv.Itoa(*app.config.install.webUISSLPort), conf)
+		if err != nil {
+			return fmt.Errorf("install: failed to dial webui for verification (%s)", err)
+		}
+		defer conn.Close()
+
+		// get top cert
+		leafCert := conn.ConnectionState().PeerCertificates[0]
+		if leafCert == nil {
+			return fmt.Errorf("install: failed to get web ui leaf cert for verification (%s)", err)
+		}
+
+		// convert pem to DER for comparison
+		pemBlock, _ := pem.Decode(certPem)
+
+		// verify cert is the correct one
+		certVerified := bytes.Equal(leafCert.Raw, pemBlock.Bytes)
+		if !certVerified {
+			return errors.New("install: web ui leaf cert does not match new cert")
+		}
+
+		app.stdLogger.Println("install: ups web ui cert verified")
+	}
+
 	return nil
 }
diff --git a/pkg/app/config.go b/pkg/app/config.go
index 6ef840b..7edf216 100644
--- a/pkg/app/config.go
+++ b/pkg/app/config.go
@@ -33,11 +33,14 @@ type config struct {
 	}
 	install struct {
 		keyCertPemCfg
-		hostAndPort    *string
+		hostname       *string
+		sshport        *int
 		fingerprint    *string
 		username       *string
 		password       *string
 		restartWebUI   *bool
+		webUISSLPort   *int
+		skipVerify     *bool
 		insecureCipher *bool
 	}
 }
@@ -92,16 +95,19 @@ func (app *app) getConfig(args []string) error {
 	cfg.install.certPemFilePath = installFlags.StringLong("certfile", "", "path and filename of the certificate in pem format")
 	cfg.install.keyPem = installFlags.StringLong("keypem", "", "string of the key in pem format")
 	cfg.install.certPem = installFlags.StringLong("certpem", "", "string of the certificate in pem format")
-	cfg.install.hostAndPort = installFlags.StringLong("apchost", "", "hostname:port of the apc ups to install the certificate on")
+	cfg.install.hostname = installFlags.StringLong("hostname", "", "hostname of the apc ups to install the certificate on")
+	cfg.install.sshport = installFlags.IntLong("sshport", 22, "apc ups ssh port number")
 	cfg.install.fingerprint = installFlags.StringLong("fingerprint", "", "the SHA256 fingerprint value of the ups' ssh server")
 	cfg.install.username = installFlags.StringLong("username", "", "username to login to the apc ups")
 	cfg.install.password = installFlags.StringLong("password", "", "password to login to the apc ups")
 	cfg.install.restartWebUI = installFlags.BoolLong("restartwebui", "some devices may need a webui restart to begin using the new cert, enabling this option sends the restart command after the p15 is installed")
+	cfg.install.webUISSLPort = installFlags.IntLong("sslport", 443, "apc ups ssl webui port number")
+	cfg.install.skipVerify = installFlags.BoolLong("skipverify", "the tool will try to connect to the UPS web UI to verify install success; this flag disables that check")
 	cfg.install.insecureCipher = installFlags.BoolLong("insecurecipher", "allows the use of insecure ssh ciphers (NOT recommended)")
 
 	installCmd := &ff.Command{
 		Name:      "install",
-		Usage:     "apc-p15-tool install --keyfile key.pem --certfile cert.pem --apchost example.com:22 --fingerprint 123abc --username apc --password test",
+		Usage:     "apc-p15-tool install --keyfile key.pem --certfile cert.pem --hostname example.com --fingerprint 123abc --username apc --password test",
 		ShortHelp: "install the specified key and cert pem files on an apc ups (they will be converted to a comaptible p15 file)",
 		Flags:     installFlags,
 		Exec:      app.cmdInstall,

From 94a76b93dececcd60e75aa3385c84560738ef0e9 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:44:35 -0400
Subject: [PATCH 38/54] v1.1.0

---
 CHANGELOG.md   | 19 +++++++++++++++++++
 pkg/app/app.go |  2 +-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e9c752..4936f32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
 # APC P15 Tool Changelog
 
+## [v1.1.0] - 2024-09-17
+
+> [!IMPORTANT]
+> The flag `apchost` on the `install` command has been renamed to
+> `hostname`. This flag should contain the hostname only. If a non-
+> default SSH port is needed, specify it in the `sshport` flag.
+
+This version brings support for for RSA 4,092 bit and EC keys. These 
+keys are only compatible with NMC3 running newer firmwares. To know 
+if your firmware is new enough, SSH into your UPS and type `ssh` and enter.
+If the UPS responds `Command Not Found` the firmware is too old or
+otherwise incompatible.
+
+This version also adds a post `install` check that connects to the web
+ui and verifies the certificate served is the expected one. You can
+specify a non standard ssl port with the `sslport` flag or skip the check
+entirely with the `skipverify` flag.
+
+
 ## [v1.0.0] - 2024-07-01
 
 First official stable release.
diff --git a/pkg/app/app.go b/pkg/app/app.go
index d2d9767..9a3f542 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "1.0.0"
+	appVersion = "1.1.0"
 )
 
 // struct for receivers to use common app pieces

From 1cfd35c4e2155457631984f1b92990d511cf93e9 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 17 Sep 2024 18:50:06 -0400
Subject: [PATCH 39/54] readme: escape asterisks

---
 README.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index d339961..1d494ed 100644
--- a/README.md
+++ b/README.md
@@ -67,9 +67,10 @@ NMC3*:
 - RSA 1,024, 2,048, 3,072, and 4,092 bit lengths.
 - ECDSA curves P-256, P-384, and P-521. 
 
-* 3,072 bit length is not officially supported by my NMC2, but appears to work
+\* 3,072 bit length is not officially supported by my NMC2, but appears to work
   fine.
-* The additional key types supported by NMC3 require newer firmware on the
+
+\* The additional key types supported by NMC3 require newer firmware on the
   device. I am unsure what the version cutoff is, but you can check support
   by connecting to the UPS via SSH and typing `ssl`. If `Command Not Found`
   is returned, the firmware is too old and only the key types listed under

From 47b964d6eef8e42bc46ca2d5ed15af3c089e6fc8 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 27 Jan 2025 19:11:06 -0500
Subject: [PATCH 40/54] install: add time check and warning

Clock skew can cause problems with SSL and certificates. Check the UPS clock and log a warning for the user if the UPS clock is more than 1 hour different than the clock of the system this tool is running on

see: https://github.com/gregtwallace/apc-p15-tool/issues/11#issuecomment-2609010943
---
 pkg/apcssh/cmd_gettime.go | 56 +++++++++++++++++++++++++++++++++++++++
 pkg/app/cmd_install.go    | 12 +++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 pkg/apcssh/cmd_gettime.go

diff --git a/pkg/apcssh/cmd_gettime.go b/pkg/apcssh/cmd_gettime.go
new file mode 100644
index 0000000..7da6397
--- /dev/null
+++ b/pkg/apcssh/cmd_gettime.go
@@ -0,0 +1,56 @@
+package apcssh
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+	"time"
+)
+
+// GetTime sends the APC `system` command and then attempts to parse the
+// response to determine the UPS current date/time.
+func (cli *Client) GetTime() (time.Time, error) {
+	result, err := cli.cmd("date")
+	if err != nil {
+		return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s)", err)
+	} else if !strings.EqualFold(result.code, "e000") {
+		return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s: %s)", result.code, result.codeText)
+	}
+
+	// capture each portion of the date information
+	regex := regexp.MustCompile(`Date:\s*(\S*)\s*[\r\n]Time:\s*(\S*)\s*[\r\n]Format:\s*(\S*)\s*[\r\n]Time Zone:\s*(\S*)\s*[\r\n]?`)
+	datePieces := regex.FindStringSubmatch(result.resultText)
+	if len(datePieces) != 5 {
+		return time.Time{}, fmt.Errorf("apcssh: failed to get time (length of datetime value pieces was %d (expected: 5))", len(datePieces))
+	}
+	dateVal := datePieces[1]
+	timeVal := datePieces[2]
+	formatUPSVal := datePieces[3]
+	timeZoneVal := datePieces[4]
+
+	// known APC UPS format strings
+	dateFormatVal := ""
+	switch formatUPSVal {
+	case "mm/dd/yyyy":
+		dateFormatVal = "01/02/2006"
+	case "dd.mm.yyyy":
+		dateFormatVal = "02.01.2006"
+	case "mmm-dd-yy":
+		dateFormatVal = "Jan-02-06"
+	case "dd-mmm-yy":
+		dateFormatVal = "02-Jan-06"
+	case "yyyy-mm-dd":
+		dateFormatVal = "2006-01-02"
+
+	default:
+		return time.Time{}, fmt.Errorf("apcssh: failed to get time (ups returned unknown format string (%s)", formatUPSVal)
+	}
+
+	// convert to time.Time
+	t, err := time.Parse(dateFormatVal+" 15:04:05 -07:00", dateVal+" "+timeVal+" "+timeZoneVal)
+	if err != nil {
+		return time.Time{}, fmt.Errorf("apcssh: failed to get time (time parse failed: %s)", err)
+	}
+
+	return t, nil
+}
diff --git a/pkg/app/cmd_install.go b/pkg/app/cmd_install.go
index a431eb8..eacda53 100644
--- a/pkg/app/cmd_install.go
+++ b/pkg/app/cmd_install.go
@@ -12,6 +12,8 @@ import (
 	"time"
 )
 
+const timeLoggingFormat = time.RFC1123Z
+
 // cmdInstall is the app's command to create apc p15 file content from key and cert
 // pem files and upload the p15 to the specified APC UPS
 func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
@@ -75,6 +77,16 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
 	}
 	app.stdLogger.Println("install: connected to ups ssh, installing ssl key and cert...")
 
+	// check time - don't fail it time is no good, just do logging here
+	upsT, err := client.GetTime()
+	if err != nil {
+		app.errLogger.Printf("warn: install: failed to fetch UPS time (%s), you should manually verify the time is correct on the UPS", err)
+	} else if upsT.After(time.Now().Add(1*time.Hour)) || upsT.Before(time.Now().Add(-1*time.Hour)) {
+		app.errLogger.Printf("warn: install: UPS clock skew detected (this system's time is %s vs. UPS time %s", time.Now().Format(timeLoggingFormat), upsT.Format(timeLoggingFormat))
+	} else {
+		app.stdLogger.Printf("install: UPS clock appears correct (%s)", upsT.Format(timeLoggingFormat))
+	}
+
 	// install SSL Cert
 	err = client.InstallSSLCert(keyP15, certPem, keyCertP15)
 	if err != nil {

From eedbdfcc2aa0e6f7b66bf143cf86aefbe11c3ef5 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 27 Jan 2025 19:22:45 -0500
Subject: [PATCH 41/54] dep: go 1.23.5

---
 .github/workflows/build_releases.yml | 2 +-
 go.mod                               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 5ff7f19..0f351d0 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -8,7 +8,7 @@ on:
 
 env:
   GITHUB_REF: ${{ github.ref }}
-  GO_VERSION: '1.23.1'
+  GO_VERSION: '1.23.5'
 
 jobs:
   build-common:
diff --git a/go.mod b/go.mod
index 11730be..0b139fe 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.23.1
+go 1.23.5
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From 7f377fc5da6d9d6c64afa73f5a730de1b2efbcd0 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 27 Jan 2025 19:23:18 -0500
Subject: [PATCH 42/54] dep: build with ubuntu-24.04

---
 .github/workflows/build_releases.yml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 0f351d0..54c4b74 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -12,7 +12,7 @@ env:
 
 jobs:
   build-common:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     steps:
       - name: Checkout Main Repo
@@ -41,7 +41,7 @@ jobs:
           path: ./CHANGELOG.md
 
   build-linux-arm64:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - name: Checkout Repo
         uses: actions/checkout@v4
@@ -90,7 +90,7 @@ jobs:
           path: ./apc-p15-install
 
   build-linux-amd64:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - name: Checkout Backend Repo
         uses: actions/checkout@v4
@@ -173,7 +173,7 @@ jobs:
 
   release-file-linux-arm64:
     needs: [build-common, build-linux-arm64]
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     steps:
       - name: Make release directory
@@ -217,7 +217,7 @@ jobs:
 
   release-file-linux-amd64:
     needs: [build-common, build-linux-amd64]
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     steps:
       - name: Make release directory
@@ -261,7 +261,7 @@ jobs:
 
   release-file-windows-amd64:
     needs: [build-common, build-windows-amd64]
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     steps:
       - name: Make release directory

From 06b76700c4568eef6e7ce6bb21a01f4351aa4baf Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 27 Jan 2025 19:47:13 -0500
Subject: [PATCH 43/54] dep: update all

---
 go.mod |  6 +++---
 go.sum | 16 ++++++++--------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/go.mod b/go.mod
index 0b139fe..f500bf1 100644
--- a/go.mod
+++ b/go.mod
@@ -4,11 +4,11 @@ go 1.23.5
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
-	github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
-	golang.org/x/crypto v0.18.0
+	github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
+	golang.org/x/crypto v0.32.0
 )
 
-require golang.org/x/sys v0.16.0 // indirect
+require golang.org/x/sys v0.29.0 // indirect
 
 replace apc-p15-tool/cmd/install_only => /cmd/install_only
 
diff --git a/go.sum b/go.sum
index 96676f0..3b8cd0d 100644
--- a/go.sum
+++ b/go.sum
@@ -2,13 +2,13 @@ github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N
 github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
 github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3UO8QfUg0Z7Y=
 github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
-github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
-github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
-golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
-golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
-golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
-golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
+github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
+github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
+golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
+golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
+golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

From 2e082a30cf5788fb1cb6331f1586def72f9b5ac0 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 27 Jan 2025 19:54:04 -0500
Subject: [PATCH 44/54] v1.2.0

---
 CHANGELOG.md   | 10 ++++++++++
 pkg/app/app.go |  2 +-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4936f32..9260307 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # APC P15 Tool Changelog
 
+## [v1.2.0] - 2025-01-27
+
+Add a new feature to `install` that checks the time of the UPS to confirm
+it is accurate. A log message is added that advises either way. Even if
+the check fails, the install still proceeds with attempting to install
+the new certificate.
+
+Dependencies were also all updated.
+
+
 ## [v1.1.0] - 2024-09-17
 
 > [!IMPORTANT]
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 9a3f542..2392056 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "1.1.0"
+	appVersion = "1.2.0"
 )
 
 // struct for receivers to use common app pieces

From c5bb8edbec46584412dc6d88c9a2efdd88e9cbcf Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 28 Jan 2025 21:04:06 -0500
Subject: [PATCH 45/54] update screenshot

---
 img/apc-p15-tool.png | Bin 104761 -> 95457 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/img/apc-p15-tool.png b/img/apc-p15-tool.png
index 807fb84cf18608689d111ae028769c0ae639f44f..c537585bbaecbccab5c6f73dba3c48be1b5f99ff 100644
GIT binary patch
literal 95457
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

literal 104761
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


From 096b50187a7d86c947a8a87f6b972ad5209bfb28 Mon Sep 17 00:00:00 2001
From: FingerlessGloves <me@FingerlessGloves.me>
Date: Tue, 18 Mar 2025 02:01:37 +0000
Subject: [PATCH 46/54] Fix GetTime for GMT users (#13)

UPS failes to use the required `+` when in the GMT timezone. Account for that.

---------

Co-authored-by: Greg T. Wallace <greg@gregtwallace.com>
---
 pkg/apcssh/cmd_gettime.go | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/pkg/apcssh/cmd_gettime.go b/pkg/apcssh/cmd_gettime.go
index 7da6397..139b0ba 100644
--- a/pkg/apcssh/cmd_gettime.go
+++ b/pkg/apcssh/cmd_gettime.go
@@ -28,6 +28,12 @@ func (cli *Client) GetTime() (time.Time, error) {
 	formatUPSVal := datePieces[3]
 	timeZoneVal := datePieces[4]
 
+	// GMT time requires + prefix
+	// APC UPS fails to use the required +, so add it
+	if timeZoneVal == "00:00" {
+		timeZoneVal = "+" + timeZoneVal
+	}
+
 	// known APC UPS format strings
 	dateFormatVal := ""
 	switch formatUPSVal {

From ad8c4e88a927b56bf0b055ed8da546983f1111c5 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 17 Mar 2025 22:05:29 -0400
Subject: [PATCH 47/54] dep: go 1.24.1

---
 .github/workflows/build_releases.yml | 2 +-
 go.mod                               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 54c4b74..7ef37de 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -8,7 +8,7 @@ on:
 
 env:
   GITHUB_REF: ${{ github.ref }}
-  GO_VERSION: '1.23.5'
+  GO_VERSION: '1.24.1'
 
 jobs:
   build-common:
diff --git a/go.mod b/go.mod
index f500bf1..9e40b33 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.23.5
+go 1.24.1
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From c67001f0e4210ada91bc74e1d4539ff5cdb046e5 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 17 Mar 2025 22:06:46 -0400
Subject: [PATCH 48/54] dep: update all

---
 go.mod |  4 ++--
 go.sum | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/go.mod b/go.mod
index 9e40b33..3c00d28 100644
--- a/go.mod
+++ b/go.mod
@@ -5,10 +5,10 @@ go 1.24.1
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
 	github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
-	golang.org/x/crypto v0.32.0
+	golang.org/x/crypto v0.36.0
 )
 
-require golang.org/x/sys v0.29.0 // indirect
+require golang.org/x/sys v0.31.0 // indirect
 
 replace apc-p15-tool/cmd/install_only => /cmd/install_only
 
diff --git a/go.sum b/go.sum
index 3b8cd0d..950e8c5 100644
--- a/go.sum
+++ b/go.sum
@@ -4,11 +4,11 @@ github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3
 github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
 github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
 github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
-golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
-golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
-golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

From e87a3100d2762a6857fe0a12b017c834ddf5c561 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Mon, 17 Mar 2025 22:06:52 -0400
Subject: [PATCH 49/54] v1.2.1

---
 CHANGELOG.md   | 7 +++++++
 pkg/app/app.go | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9260307..f99a0f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # APC P15 Tool Changelog
 
+## [v1.2.1] - 2025-03-17
+
+Fix time check for UPS when it is set to GMT timezone.
+
+All dependencies updated.
+
+
 ## [v1.2.0] - 2025-01-27
 
 Add a new feature to `install` that checks the time of the UPS to confirm
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 2392056..65b21be 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "1.2.0"
+	appVersion = "1.2.1"
 )
 
 // struct for receivers to use common app pieces

From 1392529a3f5203477dbd095b030cd763ac233f15 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 22 Apr 2025 18:27:54 -0400
Subject: [PATCH 50/54] dep: go 1.24.2

---
 .github/workflows/build_releases.yml | 2 +-
 go.mod                               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 7ef37de..3b7460d 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -8,7 +8,7 @@ on:
 
 env:
   GITHUB_REF: ${{ github.ref }}
-  GO_VERSION: '1.24.1'
+  GO_VERSION: '1.24.2'
 
 jobs:
   build-common:
diff --git a/go.mod b/go.mod
index 3c00d28..2161c8f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module apc-p15-tool
 
-go 1.24.1
+go 1.24.2
 
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4

From 3bb6b2a3c19452fb348ede80c137b4e82dfc2857 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 22 Apr 2025 18:27:54 -0400
Subject: [PATCH 51/54] dep: update all

---
 go.mod |  4 ++--
 go.sum | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/go.mod b/go.mod
index 2161c8f..76eb3ca 100644
--- a/go.mod
+++ b/go.mod
@@ -5,10 +5,10 @@ go 1.24.2
 require (
 	github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
 	github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
-	golang.org/x/crypto v0.36.0
+	golang.org/x/crypto v0.37.0
 )
 
-require golang.org/x/sys v0.31.0 // indirect
+require golang.org/x/sys v0.32.0 // indirect
 
 replace apc-p15-tool/cmd/install_only => /cmd/install_only
 
diff --git a/go.sum b/go.sum
index 950e8c5..0b94b0b 100644
--- a/go.sum
+++ b/go.sum
@@ -4,11 +4,11 @@ github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3
 github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
 github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
 github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
-golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
-golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
+golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
+golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
+golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

From 72f3f42baa8b34a7bd4523725569d4919d53112d Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 22 Apr 2025 18:27:54 -0400
Subject: [PATCH 52/54] build: add darwin arm64 & amd64

---
 .github/workflows/build_releases.yml | 174 +++++++++++++++++++++++++++
 build.ps1                            |  22 ++++
 2 files changed, 196 insertions(+)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index 3b7460d..eb1e2ff 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -40,6 +40,8 @@ jobs:
           name: CHANGELOG.md
           path: ./CHANGELOG.md
 
+###
+
   build-linux-arm64:
     runs-on: ubuntu-24.04
     steps:
@@ -171,6 +173,90 @@ jobs:
           name: apc-p15-install-windows-amd64
           path: ./apc-p15-install.exe
 
+  build-darwin-arm64:
+    runs-on: macos-15
+    steps:
+      - name: Checkout Backend Repo
+        uses: actions/checkout@v4
+        with:
+          repository: gregtwallace/apc-p15-tool
+          ref: ${{ env.GITHUB_REF }}
+          fetch-depth: 0
+
+      - name: Set up Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: '${{ env.GO_VERSION }}'
+
+      - name: Build Tool
+        run: go build -o ./apc-p15-tool -v ./cmd/tool
+        env:
+          GOOS: darwin
+          GOARCH: arm64
+          CGO_ENABLED: 0
+
+      - name: Save Compiled Binary
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-tool-darwin-arm64
+          path: ./apc-p15-tool
+
+      - name: Build Install Only
+        run: go build -o ./apc-p15-install -v ./cmd/install_only
+        env:
+          GOOS: darwin
+          GOARCH: arm64
+          CGO_ENABLED: 0
+
+      - name: Save Compiled Binary
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-install-darwin-arm64
+          path: ./apc-p15-install
+
+  build-darwin-amd64:
+    runs-on: macos-13
+    steps:
+      - name: Checkout Backend Repo
+        uses: actions/checkout@v4
+        with:
+          repository: gregtwallace/apc-p15-tool
+          ref: ${{ env.GITHUB_REF }}
+          fetch-depth: 0
+
+      - name: Set up Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: '${{ env.GO_VERSION }}'
+
+      - name: Build Tool
+        run: go build -o ./apc-p15-tool -v ./cmd/tool
+        env:
+          GOOS: darwin
+          GOARCH: amd64
+          CGO_ENABLED: 0
+
+      - name: Save Compiled Binary
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-tool-darwin-amd64
+          path: ./apc-p15-tool
+
+      - name: Build Install Only
+        run: go build -o ./apc-p15-install -v ./cmd/install_only
+        env:
+          GOOS: darwin
+          GOARCH: amd64
+          CGO_ENABLED: 0
+
+      - name: Save Compiled Binary
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-install-darwin-amd64
+          path: ./apc-p15-install
+
+###
+
   release-file-linux-arm64:
     needs: [build-common, build-linux-arm64]
     runs-on: ubuntu-24.04
@@ -302,3 +388,91 @@ jobs:
         with:
           name: apc-p15-tool_windows_amd64
           path: ./release
+
+  release-file-darwin-arm64:
+    needs: [build-common, build-darwin-arm64]
+    runs-on: ubuntu-24.04
+
+    steps:
+      - name: Make release directory
+        run: mkdir ./release
+
+      - name: Download Tool Binary
+        uses: actions/download-artifact@v4
+        with:
+          name: apc-p15-tool-darwin-arm64
+          path: ./release
+
+      - name: Download Install Binary
+        uses: actions/download-artifact@v4
+        with:
+          name: apc-p15-install-darwin-arm64
+          path: ./release
+
+      - name: Download README
+        uses: actions/download-artifact@v4
+        with:
+          name: README.md
+          path: ./release
+
+      - name: Download LICENSE
+        uses: actions/download-artifact@v4
+        with:
+          name: LICENSE.md
+          path: ./release
+
+      - name: Download CHANGELOG
+        uses: actions/download-artifact@v4
+        with:
+          name: CHANGELOG.md
+          path: ./release
+
+      - name: Save Release
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-tool_darwin_arm64
+          path: ./release
+
+  release-file-darwin-amd64:
+    needs: [build-common, build-darwin-amd64]
+    runs-on: ubuntu-24.04
+
+    steps:
+      - name: Make release directory
+        run: mkdir ./release
+
+      - name: Download Tool Binary
+        uses: actions/download-artifact@v4
+        with:
+          name: apc-p15-tool-darwin-amd64
+          path: ./release
+
+      - name: Download Install Binary
+        uses: actions/download-artifact@v4
+        with:
+          name: apc-p15-install-darwin-amd64
+          path: ./release
+
+      - name: Download README
+        uses: actions/download-artifact@v4
+        with:
+          name: README.md
+          path: ./release
+
+      - name: Download LICENSE
+        uses: actions/download-artifact@v4
+        with:
+          name: LICENSE.md
+          path: ./release
+
+      - name: Download CHANGELOG
+        uses: actions/download-artifact@v4
+        with:
+          name: CHANGELOG.md
+          path: ./release
+
+      - name: Save Release
+        uses: actions/upload-artifact@v4
+        with:
+          name: apc-p15-tool_darwin_amd64
+          path: ./release
diff --git a/build.ps1 b/build.ps1
index 7147a33..0c8774b 100644
--- a/build.ps1
+++ b/build.ps1
@@ -34,3 +34,25 @@ $env:GOARCH = "arm64"
 $env:GOOS = "linux"
 $env:CGO_ENABLED = 0
 go build -o $outDir/apc-p15-install-arm64 ./cmd/install_only
+
+# Darwin (MacOS) amd64
+$env:GOARCH = "amd64"
+$env:GOOS = "darwin"
+$env:CGO_ENABLED = 0
+go build -o $outDir/apc-p15-tool-darwin-amd64 ./cmd/tool
+
+$env:GOARCH = "amd64"
+$env:GOOS = "darwin"
+$env:CGO_ENABLED = 0
+go build -o $outDir/apc-p15-install-darwin-amd64 ./cmd/install_only
+
+# Darwin (MacOS) arm64
+$env:GOARCH = "arm64"
+$env:GOOS = "darwin"
+$env:CGO_ENABLED = 0
+go build -o $outDir/apc-p15-tool-darwin-arm64 ./cmd/tool
+
+$env:GOARCH = "arm64"
+$env:GOOS = "darwin"
+$env:CGO_ENABLED = 0
+go build -o $outDir/apc-p15-install-darwin-arm64 ./cmd/install_only

From 124c06d8be1e21786c5dfcf3d6d3f70cb5430677 Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 22 Apr 2025 18:27:55 -0400
Subject: [PATCH 53/54] build: compile linux/arm64 in native runner

---
 .github/workflows/build_releases.yml | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/.github/workflows/build_releases.yml b/.github/workflows/build_releases.yml
index eb1e2ff..5b41dbe 100644
--- a/.github/workflows/build_releases.yml
+++ b/.github/workflows/build_releases.yml
@@ -43,7 +43,7 @@ jobs:
 ###
 
   build-linux-arm64:
-    runs-on: ubuntu-24.04
+    runs-on: ubuntu-24.04-arm
     steps:
       - name: Checkout Repo
         uses: actions/checkout@v4
@@ -52,12 +52,6 @@ jobs:
           ref: ${{ env.GITHUB_REF }}
           fetch-depth: 0
 
-      - name: Update apt
-        run: sudo apt update
-
-      - name: Install cross-compiler for linux/arm64
-        run: sudo apt-get -y install gcc-aarch64-linux-gnu
-
       - name: Set up Go
         uses: actions/setup-go@v5
         with:
@@ -68,7 +62,6 @@ jobs:
         env:
           GOOS: linux
           GOARCH: arm64
-          CC: aarch64-linux-gnu-gcc
           CGO_ENABLED: 0
 
       - name: Save Compiled Binary

From 86feabd9390c26705ec9878be8d55fb67ff7a84a Mon Sep 17 00:00:00 2001
From: "Greg T. Wallace" <greg@gregtwallace.com>
Date: Tue, 22 Apr 2025 18:27:55 -0400
Subject: [PATCH 54/54] v1.2.2

---
 CHANGELOG.md   | 7 +++++++
 pkg/app/app.go | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f99a0f0..cc534a6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # APC P15 Tool Changelog
 
+## [v1.2.2] - 2025-04-22
+
+All dependencies updated.
+
+Add darwin arm64 and amd64 builds.
+
+
 ## [v1.2.1] - 2025-03-17
 
 Fix time check for UPS when it is set to GMT timezone.
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 65b21be..052a00e 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	appVersion = "1.2.1"
+	appVersion = "1.2.2"
 )
 
 // struct for receivers to use common app pieces