Posted on 12-08-2011 02:46 PM
Hey list, just wondering if anyone is using an extension attribute to report on a certificate's expiration date . . . .We use 802.1x to authorize all wired and wireless connections, so I'd like to be able to warn people before their certificates expire.
Thanks!
nick
--
Nick Kalister
Desktop Engineering
Hitachi Data Systems
Office: 408.970.4316
750 Central Expressway
Building 32 : M/S 3240
Santa Clara, CA 95050
Posted on 03-19-2012 12:28 AM
Do you use computer or user certificates? If you using user certificates that its a bit tricky as you would need to read from the users keychain. Something like this would work
#!/usr/bin/perl -w
#
open(CERTS, "security export -k login.keychain -t certs|");
my $ifile = "";
my $thisfile = "";
$username = $ENV{USER};
print "Found user name: $username
";
$dsclmodulus = `/usr/bin/dscl localhost read /Search/Users/$username UserCertificate |
/usr/bin/sed -e 's/UserCertificate://' |
/usr/bin/xxd -r -p | openssl x509 -inform DER -outform PEM |
/usr/bin/openssl x509 -noout -modulus` ;
while(<CERTS>) {
$ifile .= $_;
$thisfile .= $_;
if($_ =~ /^-+END(sw+)?sCERTIFICATE-+$/) {
$subject = `echo "$thisfile" | /usr/bin/openssl x509 -noout -subject`;
chomp($enddate = `echo "$thisfile" | /usr/bin/openssl x509 -noout -enddate`);
$enddate =~ s/notAfter=//g;
print "Checking Certificate: $subject";
if($subject =~ m/$username/){
$crtmodulus = `echo "$thisfile" | /usr/bin/openssl x509 -noout -modulus`;
print "Checking Certificate: $crtmodulus";
if($crtmodulus = $dsclmodulus){
print "Found Certificate Match
: $subject";
print "<result>$enddate</result>
";
exit 1;
}
}
$thisfile = "";
}
}
close(CERTS);
exit 0
https://gist.github.com/2101142
But has a ton of caveats , i.e would need the USER variable set, so it would run in the context of the user ( for access to the keychain) , i.e. basically in the Casper lexicon it would have to run as something like a LaunchAgent or loginhook ( with some tweaks) , and have it drop its output somewhere that would be picked up by extension attribute.
If your using computer cert this is a whole lot easier as you can just run it natively as an extension attribute as would just be reading from the system keychain.
To break the script down , its reading the (10.7 style attribute names FYI as I was testing on my own box) certificate attribute which is put there when your using a Microsoft CA ISS HTTP enrollment style system. This modulus should match whatever they are using in their keychain to auth. Once you find the certificate its trivial to grab its date.
Converting to a System cert would be pretty easy , effectively changing the command to something like
open(CERTS, "security export -k /Library/Keychains/System.keychain -t certs|");
and changing the dscl code to search for the computers cert, though I don't have something like that setup at the moment as I normally am only involved in projects that are using user certificates.
Example output
/Users/acid/Dropbox/certcheckuser
Found user name: acid
Checking Certificate: subject= /CN=Apple Configurator (00:00:00:00:00:D8)/O=sand.wallcity.org/C=US
Checking Certificate: subject= /DC=example/DC=org/DC=wallcity/CN=Users/CN=Zack Smith/emailAddress=acidprimePLEASEDONT@SPAMMEwallcity.org
Checking Certificate: Modulus=E36F027DCFB6D56FD0D990AAD6A628FEF72B608E99BBD58952566F601E2AD717D48B05E0000000BF95FDC5CD6768243228CF5EC2B85947F510D791CAE4353ED0610C9139CEBD67052B1A255152111111176885CD8299D4B874D06F71A0128982C37D4400FCE9F8EC13E4F131B84AE0C66567A5AE7FCDF27493DFC79679CCACC864749ECDC4F105ED6F722CD1D6DC85B7CE80477ECE181612E74BC220C4B941C9A95C870F98129B9E6080AB2C08D460652329A249DE04256C6E8873A227556B3563662EFA87E5EFE65B4F9D03203B38C3756BE368B024F6200B309C03756F06A495472536DB343D0C45F41D08B164107066474E653CFC0A122906B4B0B35C19F
Found Certificate Match
: subject= /DC=example/DC=org/DC=wallcity/CN=Users/CN=Zack Smith/emailAddress=acidprimePLEASEDONT@SPAMMEwallcity.org
<result>Oct 3 21:53:59 2012 GMT</result>
Posted on 03-19-2012 07:31 AM
You can easily find the owner of console and set it to a variable with
user=`ls -la /dev/console | cut -d " " -f 4`
which will tell you the currently logged in user and set it to $user. You can then do
sudo -u $user <command as user>
or simply use the security command and specify the keychain you want look at with the -k flag and specify the path to the keychain with
/Users/$user/Library/Keychains/login.keychain
Let me know if you need help with that.
Posted on 06-11-2019 05:13 PM
@acidprime I've been trying to do something similar, to report if there is an expired AD user cert in the login.keychain, or if there is no AD user cert in the login.keychain (vpn issues are generally caused by one or the other condition). The issue I continually run up against (confirmed by others in many other posts) is that when the login.keychain has multiple user certificates with the same name, only one expiration date will be returned. I haven't been able to find a way to loop through login.keychain certificates with the same name and report on each expiration date. I've tried an array, but no luck; I can only report on login.keychain certificate expiration dates as long as no more than one certificate exists with the same name.
Posted on 06-30-2020 10:07 PM
When running
/usr/bin/security find-certificate -a -p -Z /Library/Keychains/apsd.keychain | /usr/bin/openssl x509 -noout -enddate| cut -f2 -d=
I end up with Mar 13 03:57:11 2021 GMT which does not play nice as a Date EA. How would we change this to the more EA friendly yyyy-mm-dd format?
Posted on 01-06-2021 08:16 AM
@swhps You can add
| date +"%Y-%m-%d %T"
to the end and that should format it correctly.
So the entire string would be...
/usr/bin/security find-certificate -a -p -Z /Library/Keychains/apsd.keychain | /usr/bin/openssl x509 -noout -enddate | cut -f2 -d= | date +"%Y-%m-%d %T"