Skip to content

Commit c673862

Browse files
committed
leverage objective C APIs on macos to install the SSL certificate
1 parent 35f163c commit c673862

File tree

4 files changed

+99
-30
lines changed

4 files changed

+99
-30
lines changed

certificates/certificates.go

-29
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ import (
3030
"math/big"
3131
"net"
3232
"os"
33-
"os/exec"
34-
"runtime"
3533
"strings"
3634
"text/template"
3735
"time"
@@ -274,33 +272,6 @@ func GenerateCertificates(certsDir *paths.Path) {
274272
}
275273
}
276274

277-
// InstallCertificates will install the certificates in the system keychain
278-
func InstallCertificates(certsDir *paths.Path) {
279-
switch runtime.GOOS {
280-
case "darwin":
281-
command := fmt.Sprintf(`tell application "Terminal"
282-
reopen
283-
activate
284-
delay 1
285-
do script "sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain %s/ca.cert.pem; echo '\\nYou can now close this window.\\n\\n' ; exit" in front window
286-
end tell`, certsDir.String())
287-
log.Info("osascript", "-e", command)
288-
stdoutStderr, err := exec.Command("osascript", "-e", command).CombinedOutput()
289-
if err != nil {
290-
log.Errorf("cannot install certificate in the system keychain: %s", err)
291-
}
292-
log.Infof("stdout: %s", stdoutStderr)
293-
case "windows":
294-
stdoutStderr, err := exec.Command("certmgr.exe", "-add", certsDir.String()+`/ca.cert.cer`, "-s", "-r", "currentUser", "root").CombinedOutput()
295-
if err != nil {
296-
log.Errorf("cannot install certificate in the system keychain: %s", err)
297-
}
298-
log.Infof("stdout: %s", stdoutStderr)
299-
default:
300-
log.Infof("cannot install certificate: OS not supported")
301-
}
302-
}
303-
304275
// CertHandler will expone the certificate (we do not know why this was required)
305276
func CertHandler(c *gin.Context) {
306277
if strings.Contains(c.Request.UserAgent(), "Firefox") {

certificates/install_darwin.go

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2023 Arduino SA
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published
5+
// by the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU Affero General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Affero General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
package certificates
17+
18+
//inspired by https://stackoverflow.com/questions/12798950/ios-install-ssl-certificate-programmatically
19+
20+
/*
21+
#cgo CFLAGS: -x objective-c
22+
#cgo LDFLAGS: -framework Cocoa
23+
#import <Cocoa/Cocoa.h>
24+
25+
void installCert(const char *path) {
26+
NSURL *url = [NSURL fileURLWithPath:@(path) isDirectory:NO];
27+
NSData *rootCertData = [NSData dataWithContentsOfURL:url];
28+
29+
OSStatus err = noErr;
30+
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);
31+
32+
CFTypeRef result;
33+
34+
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
35+
(id)kSecClassCertificate, kSecClass,
36+
rootCert, kSecValueRef,
37+
nil];
38+
39+
err = SecItemAdd((CFDictionaryRef)dict, &result);
40+
41+
if( err == noErr) {
42+
NSLog(@"Install root certificate success");
43+
} else if( err == errSecDuplicateItem ) {
44+
NSLog(@"duplicate root certificate entry");
45+
} else {
46+
NSLog(@"install root certificate failure");
47+
}
48+
49+
NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};
50+
err = SecTrustSettingsSetTrustSettings(rootCert, kSecTrustSettingsDomainUser, (__bridge CFTypeRef)(newTrustSettings));
51+
if (err != errSecSuccess) {
52+
NSLog(@"Could not change the trust setting for a certificate. Error: %d", err);
53+
exit(0);
54+
}
55+
}
56+
57+
*/
58+
import "C"
59+
import (
60+
log "github.com/sirupsen/logrus"
61+
62+
"github.com/arduino/go-paths-helper"
63+
)
64+
65+
// InstallCertificates will install the certificates in the system keychain on macos
66+
func InstallCertificate(cert *paths.Path) {
67+
log.Infof("Installing certificate: %s", cert)
68+
C.installCert(C.CString(cert.String()))
69+
}

certificates/install_default.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2023 Arduino SA
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published
5+
// by the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU Affero General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Affero General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
//go:build !darwin
17+
18+
package certificates
19+
20+
import (
21+
log "github.com/sirupsen/logrus"
22+
23+
"github.com/arduino/go-paths-helper"
24+
)
25+
26+
// InstallCertificates won't do anything on unsupported Operative Systems
27+
func InstallCertificate(cert *paths.Path) {
28+
log.Warn("platform not supported for the certificate install")
29+
}

systray/systray_real.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (s *Systray) start() {
9090
s.updateMenuItem(mRmCrashes, config.LogsIsEmpty())
9191
case <-mGenCerts.ClickedCh:
9292
cert.GenerateCertificates(config.GetCertificatesDir())
93-
cert.InstallCertificates(config.GetCertificatesDir())
93+
cert.InstallCertificate(config.GetCertificatesDir().Join("ca.cert.cer"))
9494
s.Restart()
9595
case <-mPause.ClickedCh:
9696
s.Pause()

0 commit comments

Comments
 (0)