Skip to content

Commit b3aa9ab

Browse files
Manage errors that may occur retrieving certificates expiration date
1 parent b43226d commit b3aa9ab

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

Diff for: certificates/certificates.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,12 @@ func DeleteCertificates(certDir *paths.Path) {
270270
}
271271

272272
// IsExpired checks if a certificate is expired
273-
func IsExpired() bool {
273+
func IsExpired() (bool, error) {
274274
bound := time.Now().AddDate(0, 1, 0)
275-
// TODO: manage errors
276-
dateS, _ := GetExpirationDate()
275+
dateS, err := GetExpirationDate()
276+
if err != nil {
277+
return false, err
278+
}
277279
date, _ := time.Parse(time.DateTime, strings.ReplaceAll(dateS, " +0000", ""))
278-
return date.Before(bound)
280+
return date.Before(bound), nil
279281
}

Diff for: certificates/install_darwin.go

+33-13
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ const char *evaluateCert(){
140140
return "";
141141
}
142142
143-
const char *getExpirationDate(){
143+
const char *getExpirationDate(char *expirationDate){
144144
// Create a key-value dictionary used to query the Keychain and look for the "Arduino" root certificate.
145145
NSDictionary *getquery = @{
146146
(id)kSecClass: (id)kSecClassCertificate,
@@ -154,24 +154,39 @@ const char *getExpirationDate(){
154154
// Use this function to check for errors
155155
err = SecItemCopyMatching((CFDictionaryRef)getquery, (CFTypeRef *)&cert);
156156
157-
if (err != errSecItemNotFound && err != noErr){
157+
if (err != noErr){
158158
NSString *errString = [@"Error: " stringByAppendingFormat:@"%d", err];
159159
NSLog(@"%@", errString);
160-
return "";
160+
return [errString cStringUsingEncoding:[NSString defaultCStringEncoding]];
161161
}
162162
163163
// Get data from the certificate. We just need the "invalidity date" property.
164164
CFDictionaryRef valuesDict = SecCertificateCopyValues(cert, (__bridge CFArrayRef)@[(__bridge id)kSecOIDInvalidityDate], NULL);
165165
166-
// TODO: Error checking.
167-
CFDictionaryRef invalidityDateDictionaryRef = CFDictionaryGetValue(valuesDict, kSecOIDInvalidityDate);
168-
CFTypeRef invalidityRef = CFDictionaryGetValue(invalidityDateDictionaryRef, kSecPropertyKeyValue);
169-
id expirationDateValue = CFBridgingRelease(invalidityRef);
170-
171-
CFRelease(valuesDict);
166+
id expirationDateValue;
167+
if(valuesDict){
168+
CFDictionaryRef invalidityDateDictionaryRef = CFDictionaryGetValue(valuesDict, kSecOIDInvalidityDate);
169+
if(invalidityDateDictionaryRef){
170+
CFTypeRef invalidityRef = CFDictionaryGetValue(invalidityDateDictionaryRef, kSecPropertyKeyValue);
171+
if(invalidityRef){
172+
expirationDateValue = CFBridgingRelease(invalidityRef);
173+
}
174+
}
175+
CFRelease(valuesDict);
176+
}
172177
173178
NSString *outputString = [@"" stringByAppendingFormat:@"%@", expirationDateValue];
174-
return [outputString cStringUsingEncoding:[NSString defaultCStringEncoding]];
179+
if([outputString isEqualToString:@""]){
180+
NSString *errString = @"Error: the expiration date of the certificate could not be found";
181+
NSLog(@"%@", errString);
182+
return [errString cStringUsingEncoding:[NSString defaultCStringEncoding]];
183+
}
184+
185+
// This workaround allows to obtain the expiration date alongside the error message
186+
strncpy(expirationDate, [outputString cStringUsingEncoding:[NSString defaultCStringEncoding]], 32);
187+
expirationDate[32-1] = 0;
188+
189+
return "";
175190
}
176191
*/
177192
import "C"
@@ -233,10 +248,15 @@ func EvaluateCertificates() error {
233248
// GetExpirationDate returns the expiration date of a certificate stored in the keychain
234249
func GetExpirationDate() (string, error) {
235250
log.Infof("Retrieving certificate's expiration date")
236-
p := C.getExpirationDate()
251+
dateString := C.CString("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") // 32 characters string
252+
defer C.free(unsafe.Pointer(dateString))
253+
p := C.getExpirationDate(dateString)
237254
s := C.GoString(p)
238255
if len(s) != 0 {
239-
return s, nil
256+
oscmd := exec.Command("osascript", "-e", "display dialog \""+s+"\" buttons \"OK\" with title \"Arduino Agent: Error retrieving expiration date\"")
257+
_ = oscmd.Run()
258+
return "", errors.New(s)
240259
}
241-
return "", nil
260+
date := C.GoString(dateString)
261+
return date, nil
242262
}

Diff for: systray/systray_real.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ func (s *Systray) start() {
135135
oscmd := exec.Command("osascript", "-e", "display dialog \""+infoMsg+"\" buttons \"OK\" with title \"Arduino Agent: certificates info\"")
136136
_ = oscmd.Run()
137137
case <-mRenewCerts.ClickedCh:
138-
if cert.IsExpired() {
138+
if expired, err := cert.IsExpired(); err != nil {
139+
log.Errorf("cannot check if certificates are expired something went wrong: %s", err)
140+
} else if expired {
139141
err := cert.UninstallCertificates()
140142
if err != nil {
141143
log.Errorf("cannot uninstall certificates something went wrong: %s", err)

0 commit comments

Comments
 (0)