Skip to content

Commit 51f4ee4

Browse files
Remove existing certificates from the keychain (#933)
* Add function to uninstall certificate from the system keychain * Remove certificates from the keychain using the systray icon * Improve error messages when installing and uninstalling certificates * Remove certificate from the keychain if an error occurs during install
1 parent b0a9091 commit 51f4ee4

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

certificates/install_darwin.go

+44-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ package certificates
1818
//inspired by https://stackoverflow.com/questions/12798950/ios-install-ssl-certificate-programmatically
1919

2020
/*
21+
// Explicitly tell the GCC compiler that the language is Objective-C.
2122
#cgo CFLAGS: -x objective-c
23+
// Pass the list of macOS frameworks needed by this piece of Objective-C code.
2224
#cgo LDFLAGS: -framework Cocoa
2325
#import <Cocoa/Cocoa.h>
2426
@@ -61,6 +63,32 @@ const char *installCert(const char *path) {
6163
return "";
6264
}
6365
66+
const char *uninstallCert() {
67+
// Each line is a key-value of the dictionary. Note: the the inverted order, value first then key.
68+
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
69+
(id)kSecClassCertificate, kSecClass,
70+
CFSTR("Arduino"), kSecAttrLabel,
71+
kSecMatchLimitOne, kSecMatchLimit,
72+
kCFBooleanTrue, kSecReturnAttributes,
73+
nil];
74+
75+
OSStatus err = noErr;
76+
// Use this function to check for errors
77+
err = SecItemCopyMatching((CFDictionaryRef)dict, nil);
78+
if (err == noErr) {
79+
err = SecItemDelete((CFDictionaryRef)dict);
80+
if (err != noErr) {
81+
NSString *errString = [@"Could not delete the certificates. Error: " stringByAppendingFormat:@"%d", err];
82+
NSLog(@"%@", errString);
83+
return [errString cStringUsingEncoding:[NSString defaultCStringEncoding]];;
84+
}
85+
} else if (err != errSecItemNotFound){
86+
NSString *errString = [@"Error: " stringByAppendingFormat:@"%d", err];
87+
NSLog(@"%@", errString);
88+
return [errString cStringUsingEncoding:[NSString defaultCStringEncoding]];;
89+
}
90+
return "";
91+
}
6492
*/
6593
import "C"
6694
import (
@@ -82,7 +110,22 @@ func InstallCertificate(cert *paths.Path) error {
82110
p := C.installCert(ccert)
83111
s := C.GoString(p)
84112
if len(s) != 0 {
85-
oscmd := exec.Command("osascript", "-e", "display dialog \""+s+"\" buttons \"OK\" with title \"Error installing certificates\"")
113+
oscmd := exec.Command("osascript", "-e", "display dialog \""+s+"\" buttons \"OK\" with title \"Arduino Agent: Error installing certificates\"")
114+
_ = oscmd.Run()
115+
_ = UninstallCertificates()
116+
return errors.New(s)
117+
}
118+
return nil
119+
}
120+
121+
// UninstallCertificates will uninstall the certificates from the system keychain on macos,
122+
// if something goes wrong will show a dialog with the error and return an error
123+
func UninstallCertificates() error {
124+
log.Infof("Uninstalling certificates")
125+
p := C.uninstallCert()
126+
s := C.GoString(p)
127+
if len(s) != 0 {
128+
oscmd := exec.Command("osascript", "-e", "display dialog \""+s+"\" buttons \"OK\" with title \"Arduino Agent: Error uninstalling certificates\"")
86129
_ = oscmd.Run()
87130
return errors.New(s)
88131
}

certificates/install_default.go

+6
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,9 @@ func InstallCertificate(cert *paths.Path) error {
3030
log.Warn("platform not supported for the certificate install")
3131
return errors.New("platform not supported for the certificate install")
3232
}
33+
34+
// UninstallCertificates won't do anything on unsupported Operative Systems
35+
func UninstallCertificates() error {
36+
log.Warn("platform not supported for the certificates uninstall")
37+
return errors.New("platform not supported for the certificates uninstall")
38+
}

systray/systray_real.go

+12
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,15 @@ func (s *Systray) start() {
6464
s.updateMenuItem(mRmCrashes, config.LogsIsEmpty())
6565

6666
mGenCerts := systray.AddMenuItem("Generate and Install HTTPS certificates", "HTTPS Certs")
67+
mRemoveCerts := systray.AddMenuItem("Remove HTTPS certificates", "")
6768
// On linux/windows chrome/firefox/edge(chromium) the agent works without problems on plain HTTP,
6869
// so we disable the menuItem to generate/install the certificates
6970
if runtime.GOOS != "darwin" {
7071
s.updateMenuItem(mGenCerts, true)
72+
s.updateMenuItem(mRemoveCerts, true)
7173
} else {
7274
s.updateMenuItem(mGenCerts, config.CertsExist())
75+
s.updateMenuItem(mRemoveCerts, !config.CertsExist())
7376
}
7477

7578
// Add pause/quit
@@ -103,6 +106,15 @@ func (s *Systray) start() {
103106
cert.DeleteCertificates(certDir)
104107
}
105108
s.Restart()
109+
case <-mRemoveCerts.ClickedCh:
110+
err := cert.UninstallCertificates()
111+
if err != nil {
112+
log.Errorf("cannot uninstall certificates something went wrong: %s", err)
113+
} else {
114+
certDir := config.GetCertificatesDir()
115+
cert.DeleteCertificates(certDir)
116+
}
117+
s.Restart()
106118
case <-mPause.ClickedCh:
107119
s.Pause()
108120
case <-mQuit.ClickedCh:

0 commit comments

Comments
 (0)