@ -51,40 +51,61 @@ var (
errBadRequest = errors . New ( "malformed request" )
errBadRequest = errors . New ( "malformed request" )
)
)
// findIdentity locates an identity from the Windows or Darwin certificate
func isSupportedCertificate ( cert * x509 . Certificate ) bool {
// store. It returns the first certificate with a matching Subject anywhere in
return cert . PublicKeyAlgorithm == x509 . RSA
// its certificate chain, so it is possible to search for the leaf certificate,
}
// intermediate CA or root CA. If err is nil then the returned identity will
// never be nil (if no identity is found, the error errNoMatch will be
func isSubjectInChain ( subject string , chain [ ] * x509 . Certificate ) bool {
// returned). If an identity is returned then its certificate chain is also
if len ( chain ) == 0 || chain [ 0 ] == nil {
// returned.
return false
func findIdentity ( subject string , st certstore . Store ) ( certstore . Identity , [ ] * x509 . Certificate , error ) {
}
ids , err := st . Identities ( )
if err != nil {
for _ , c := range chain {
return nil , nil , err
if c == nil {
continue
}
if c . Subject . String ( ) == subject {
return true
}
}
}
var selected certstore . Identity
return false
var chain [ ] * x509 . Certificate
}
func selectIdentityFromSlice ( subject string , ids [ ] certstore . Identity ) ( certstore . Identity , [ ] * x509 . Certificate ) {
for _ , id := range ids {
for _ , id := range ids {
chain , err = id . CertificateChain ( )
chain , err : = id . CertificateChain ( )
if err != nil {
if err != nil {
continue
continue
}
}
if chain [ 0 ] . PublicKeyAlgorithm != x509 . RSA {
if ! isSupportedCertificate ( chain [ 0 ] ) {
continue
continue
}
}
for _ , c := range chain {
if isSubjectInChain ( subject , chain ) {
if c . Subject . String ( ) == subject {
return id , chain
selected = id
break
}
}
}
}
}
return nil , nil
}
// findIdentity locates an identity from the Windows or Darwin certificate
// store. It returns the first certificate with a matching Subject anywhere in
// its certificate chain, so it is possible to search for the leaf certificate,
// intermediate CA or root CA. If err is nil then the returned identity will
// never be nil (if no identity is found, the error errNoMatch will be
// returned). If an identity is returned then its certificate chain is also
// returned.
func findIdentity ( subject string , st certstore . Store ) ( certstore . Identity , [ ] * x509 . Certificate , error ) {
ids , err := st . Identities ( )
if err != nil {
return nil , nil , err
}
selected , chain := selectIdentityFromSlice ( subject , ids )
for _ , id := range ids {
for _ , id := range ids {
if id != selected {
if id != selected {
id . Close ( )
id . Close ( )