// Fetches the CA info. Unlike other certificates, the CA info is stored // in the backend as a CertBundle, because we are storing its private key func fetchCAInfo(req *logical.Request) (*certutil.ParsedCertBundle, error) { bundleEntry, err := req.Storage.Get("config/ca_bundle") if err != nil { return nil, certutil.InternalError{Err: fmt.Sprintf("Unable to fetch local CA certificate/key: %s", err)} } if bundleEntry == nil { return nil, certutil.UserError{Err: fmt.Sprintf("Backend must be configured with a CA certificate/key")} } var bundle certutil.CertBundle if err := bundleEntry.DecodeJSON(&bundle); err != nil { return nil, certutil.InternalError{Err: fmt.Sprintf("Unable to decode local CA certificate/key: %s", err)} } parsedBundle, err := bundle.ToParsedCertBundle() if err != nil { return nil, certutil.InternalError{Err: err.Error()} } if parsedBundle.Certificate == nil { return nil, certutil.InternalError{Err: "Stored CA information not able to be parsed"} } return parsedBundle, nil }
// Performs some validity checking on the returned bundles func checkCertsAndPrivateKey(keyType string, usage certUsage, validity time.Duration, certBundle *certutil.CertBundle) (*certutil.ParsedCertBundle, error) { parsedCertBundle, err := certBundle.ToParsedCertBundle() if err != nil { return nil, fmt.Errorf("Error parsing cert bundle: %s", err) } switch { case parsedCertBundle.Certificate == nil: return nil, fmt.Errorf("Did not find a certificate in the cert bundle") case parsedCertBundle.IssuingCA == nil: return nil, fmt.Errorf("Did not find a CA in the cert bundle") case parsedCertBundle.PrivateKey == nil: return nil, fmt.Errorf("Did not find a private key in the cert bundle") case parsedCertBundle.PrivateKeyType == certutil.UnknownPrivateKey: return nil, fmt.Errorf("Could not figure out type of private key") } switch { case parsedCertBundle.PrivateKeyType == certutil.RSAPrivateKey && keyType != "rsa": fallthrough case parsedCertBundle.PrivateKeyType == certutil.ECPrivateKey && keyType != "ec": return nil, fmt.Errorf("Given key type does not match type found in bundle") } cert := parsedCertBundle.Certificate // There should only be one usage type, because only one is requested // in the tests if len(cert.ExtKeyUsage) != 1 { return nil, fmt.Errorf("Got wrong size key usage in generated cert") } switch usage { case serverUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageServerAuth { return nil, fmt.Errorf("Bad key usage") } case clientUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageClientAuth { return nil, fmt.Errorf("Bad key usage") } case codeSigningUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageCodeSigning { return nil, fmt.Errorf("Bad key usage") } } if math.Abs(float64(time.Now().Unix()-cert.NotBefore.Unix())) > 10 { return nil, fmt.Errorf("Validity period starts out of range") } if math.Abs(float64(time.Now().Add(validity).Unix()-cert.NotAfter.Unix())) > 10 { return nil, fmt.Errorf("Validity period of %d too large vs max of 10", cert.NotAfter.Unix()) } return parsedCertBundle, nil }
// Fetches the CA info. Unlike other certificates, the CA info is stored // in the backend as a CertBundle, because we are storing its private key func fetchCAInfo(req *logical.Request) (*caInfoBundle, error) { bundleEntry, err := req.Storage.Get("config/ca_bundle") if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch local CA certificate/key: %v", err)} } if bundleEntry == nil { return nil, errutil.UserError{Err: "backend must be configured with a CA certificate/key"} } var bundle certutil.CertBundle if err := bundleEntry.DecodeJSON(&bundle); err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to decode local CA certificate/key: %v", err)} } parsedBundle, err := bundle.ToParsedCertBundle() if err != nil { return nil, errutil.InternalError{Err: err.Error()} } if parsedBundle.Certificate == nil { return nil, errutil.InternalError{Err: "stored CA information not able to be parsed"} } caInfo := &caInfoBundle{*parsedBundle, nil} entries, err := getURLs(req) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch URL information: %v", err)} } if entries == nil { entries = &urlEntries{ IssuingCertificates: []string{}, CRLDistributionPoints: []string{}, OCSPServers: []string{}, } } caInfo.URLs = entries return caInfo, nil }
// Performs some validity checking on the returned bundles func checkCertsAndPrivateKey(keyType string, key crypto.Signer, usage certUsage, validity time.Duration, certBundle *certutil.CertBundle) (*certutil.ParsedCertBundle, error) { parsedCertBundle, err := certBundle.ToParsedCertBundle() if err != nil { return nil, fmt.Errorf("Error parsing cert bundle: %s", err) } if key != nil { switch keyType { case "rsa": parsedCertBundle.PrivateKeyType = certutil.RSAPrivateKey parsedCertBundle.PrivateKey = key parsedCertBundle.PrivateKeyBytes = x509.MarshalPKCS1PrivateKey(key.(*rsa.PrivateKey)) case "ec": parsedCertBundle.PrivateKeyType = certutil.ECPrivateKey parsedCertBundle.PrivateKey = key parsedCertBundle.PrivateKeyBytes, err = x509.MarshalECPrivateKey(key.(*ecdsa.PrivateKey)) if err != nil { return nil, fmt.Errorf("Error parsing EC key: %s", err) } } } switch { case parsedCertBundle.Certificate == nil: return nil, fmt.Errorf("Did not find a certificate in the cert bundle") case parsedCertBundle.IssuingCA == nil: return nil, fmt.Errorf("Did not find a CA in the cert bundle") case parsedCertBundle.PrivateKey == nil: return nil, fmt.Errorf("Did not find a private key in the cert bundle") case parsedCertBundle.PrivateKeyType == certutil.UnknownPrivateKey: return nil, fmt.Errorf("Could not figure out type of private key") } switch { case parsedCertBundle.PrivateKeyType == certutil.RSAPrivateKey && keyType != "rsa": fallthrough case parsedCertBundle.PrivateKeyType == certutil.ECPrivateKey && keyType != "ec": return nil, fmt.Errorf("Given key type does not match type found in bundle") } cert := parsedCertBundle.Certificate // There should only be one usage type, because only one is requested // in the tests if len(cert.ExtKeyUsage) != 1 { return nil, fmt.Errorf("Got wrong size key usage in generated cert; values are %#v", cert.ExtKeyUsage) } switch usage { case emailProtectionUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageEmailProtection { return nil, fmt.Errorf("Bad key usage") } case serverUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageServerAuth { return nil, fmt.Errorf("Bad key usage") } case clientUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageClientAuth { return nil, fmt.Errorf("Bad key usage") } case codeSigningUsage: if cert.ExtKeyUsage[0] != x509.ExtKeyUsageCodeSigning { return nil, fmt.Errorf("Bad key usage") } } // 40 seconds since we add 30 second slack for clock skew if math.Abs(float64(time.Now().Unix()-cert.NotBefore.Unix())) > 40 { return nil, fmt.Errorf("Validity period starts out of range") } if !cert.NotBefore.Before(time.Now().Add(-10 * time.Second)) { return nil, fmt.Errorf("Validity period not far enough in the past") } if math.Abs(float64(time.Now().Add(validity).Unix()-cert.NotAfter.Unix())) > 10 { return nil, fmt.Errorf("Validity period of %d too large vs max of 10", cert.NotAfter.Unix()) } return parsedCertBundle, nil }