2009-11-29 5 views
11

Ho difficoltà a trovare una risposta ai miei problemi di codifica.Come ottenere le informazioni sul certificato dell'applicazione con codice

Abbiamo un'applicazione per Mac OS scritta in Cocoa. Infine, abbiamo fatto il nostro codesigning, ma vorrei aggiungere un ulteriore controllo di sicurezza - all'interno dell'eseguibile stesso.

La mia idea è di convalidare l'impronta digitale del certificato con cui viene firmato l'eseguibile corrente quando viene avviato. Se è mancante o non valido (confrontato con un hash hardcoded all'interno dell'applicazione), lo spegniamo.

Finora, non sono stato in grado di ottenere il certificato utilizzato per codificare l'eseguibile in modo programmatico e controllarne i dati.

Qualcuno ha un indizio su come farlo?

Grazie mille! Martin K.

risposta

4

Se il targeting è 10.6+, è possibile utilizzare le funzioni di firma codice nel framework di sicurezza (documentation), in particolare SecCodeCheckValidity. In caso contrario, il codice sorgente per il sistema di firma codice è libsecurity_codesigning.

Poiché si sta utilizzando la firma del codice per autenticare il codice, è necessario convalidare anche il requisito designato con SecCodeCopyDesignatedRequirement.

8

Grazie amico!

Sono riuscito a farlo per 10.6 con la nuova funzionalità, ma il problema è che sto prendendo di mira 10.5 e 10.6, almeno fino a quando passa un po 'di tempo.

Devo passare ancora un po 'di tempo in libsecurity_codesigning in modo che questo possa essere completato anche per 10.5.

Ma, per le persone che sono alla ricerca di soluzioni pronte da queste parti, qui è che cosa ho finito con:

SecStaticCodeRef ref = NULL; 

NSURL * url = [NSURL URLWithString:[[NSBundle mainBundle] executablePath]]; 

OSStatus status; 

// obtain the cert info from the executable 
status = SecStaticCodeCreateWithPath((CFURLRef)url, kSecCSDefaultFlags, &ref); 

if (ref == NULL) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE); 
if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE); 

SecRequirementRef req = NULL; 

// this is the public SHA1 fingerprint of the cert match string 
NSString * reqStr = [NSString stringWithFormat:@"%@ %@ = %@%@%@", 
    @"certificate", 
    @"leaf", 
    @"H\"66875745923F01", 
    @"F122B387B0F943", 
    @"X7D981183151\"" 
    ]; 

// create the requirement to check against 
status = SecRequirementCreateWithString((CFStringRef)reqStr, kSecCSDefaultFlags, &req); 

if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE); 
if (req == NULL) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE); 

status = SecStaticCodeCheckValidity(ref, kSecCSCheckAllArchitectures, req); 

if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE); 

CFRelease(ref); 
CFRelease(req); 

LogDebug(@"Code signature was checked and it seems OK"); 
+0

Grazie per la condivisione! BTW, presumo che NSURL * url = [[NSBundle mainBundle] bundleURL] nella seconda riga possa essere utilizzato per verificare una validità dell'intero pacchetto, comprese risorse ed eseguibili. È corretto? – Stream

+0

hai mai funzionato su 10.5? – Richard

+0

No, ma penso che sia un po 'tardi per quello ora :) –

0

Nella risposta di cui sopra, la seconda linea dovrebbe essere:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] executablePath]]; 

Se si utilizza la risposta accettata (contenente [NSURL URLWithString:...]), allora url sarà nullo se il nome della propria app contiene uno spazio o se -executablePath restituisce un percorso contenente determinati caratteri. Ciò, naturalmente, farà fallire l'intera convalida.

(Ho fatto questa seconda risposta piuttosto che un commento per l'evidenziazione della sintassi.)