func TestVerifyMac(t *testing.T) { td := macData{ Mac: digestInfo{ Digest: []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93}, }, MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, Iterations: 2048, } message := []byte{11, 12, 13, 14, 15} password, _ := bmpString([]byte("")) td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3}) err := verifyMac(&td, message, password) if _, ok := err.(NotImplementedError); !ok { t.Errorf("err: %v", err) } td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) err = verifyMac(&td, message, password) if err != ErrIncorrectPassword { t.Errorf("Expected incorrect password, got err: %v", err) } password, _ = bmpString([]byte("Sesame open")) err = verifyMac(&td, message, password) if err != nil { t.Errorf("err: %v", err) } }
func TestComputeMac(t *testing.T) { td := macData{ MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, Iterations: 2048, } message := []byte{11, 12, 13, 14, 15} password, _ := bmpString([]byte("Sesame open")) td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3}) err := computeMac(&td, message, password) if _, ok := err.(NotImplementedError); !ok { t.Errorf("err: %v", err) } td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) err = computeMac(&td, message, password) if err != nil { t.Errorf("err: %v", err) } expectedDigest := []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93} if bytes.Compare(td.Mac.Digest, expectedDigest) != 0 { t.Errorf("Computed incorrect MAC; expected MAC to be '%d' but got '%d'", expectedDigest, td.Mac.Digest) } }
func TestPbDecrypterFor(t *testing.T) { params, _ := asn1.Marshal(pbeParams{ Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, Iterations: 2048, }) alg := pkix.AlgorithmIdentifier{ Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), Parameters: asn1.RawValue{ FullBytes: params, }, } pass, _ := bmpString([]byte("Sesame open")) _, err := pbDecrypterFor(alg, pass) if _, ok := err.(NotImplementedError); !ok { t.Errorf("expected not implemented error, got: %T %s", err, err) } alg.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) cbc, err := pbDecrypterFor(alg, pass) if err != nil { t.Errorf("err: %v", err) } M := []byte{1, 2, 3, 4, 5, 6, 7, 8} expectedM := []byte{185, 73, 135, 249, 137, 1, 122, 247} cbc.CryptBlocks(M, M) if bytes.Compare(M, expectedM) != 0 { t.Errorf("expected M to be '%d', but found '%d", expectedM, M) } }
// CreateRequest returns a DER-encoded, OCSP request for the status of cert. If // opts is nil then sensible defaults are used. func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) { hashFunc := opts.hash() // OCSP seems to be the only place where these raw hash identifiers are // used. I took the following from // http://msdn.microsoft.com/en-us/library/ff635603.aspx var hashOID asn1.ObjectIdentifier switch hashFunc { case crypto.SHA1: hashOID = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) case crypto.SHA256: hashOID = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}) case crypto.SHA384: hashOID = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}) case crypto.SHA512: hashOID = asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}) default: return nil, x509.ErrUnsupportedAlgorithm } if !hashFunc.Available() { return nil, x509.ErrUnsupportedAlgorithm } h := opts.hash().New() var publicKeyInfo struct { Algorithm pkix.AlgorithmIdentifier PublicKey asn1.BitString } if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { return nil, err } h.Write(publicKeyInfo.PublicKey.RightAlign()) issuerKeyHash := h.Sum(nil) h.Reset() h.Write(issuer.RawSubject) issuerNameHash := h.Sum(nil) return asn1.Marshal(ocspRequest{ tbsRequest{ Version: 0, RequestList: []request{ { Cert: certID{ pkix.AlgorithmIdentifier{ Algorithm: hashOID, Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, }, issuerNameHash, issuerKeyHash, cert.SerialNumber, }, }, }, }, }) }
func BuildIdentifierCaches(mib_file []string) { args := []string{"-f", "identifiers", "-k", "-u"} for _, x := range mib_file { args = append(args, x) } cmd := exec.Command("smidump", args...) stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) cmd.Stdout = stdout cmd.Stderr = stderr cmd.Run() scanner := bufio.NewScanner(stdout) for scanner.Scan() { cols := pat_split.Split(scanner.Text(), -1) if len(cols) >= 4 { if oid, err := parseOID(cols[3]); err == nil { if len(oid) > max_cache_prefix_oid_length { max_cache_prefix_oid_length = len(oid) } if len(oid) < min_cache_prefix_oid_length { min_cache_prefix_oid_length = len(oid) } key := asn1.ObjectIdentifier(oid).String() value := fmt.Sprintf("%s::%s", cols[0], cols[1]) cache_prefix[key] = value } } } }
func TestPbEncrypt(t *testing.T) { tests := [][]byte{ []byte("A secret!"), []byte("A secret"), } expected := [][]byte{ []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes } for i, c := range tests { td := testDecryptable{ algorithm: pkix.AlgorithmIdentifier{ Algorithm: asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}), // SHA1/3TDES Parameters: pbeParams{ Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"), Iterations: 4096, }.RawASN1(), }, } p, _ := bmpString("sesame") err := pbEncrypt(&td, c, p) if err != nil { t.Errorf("error encrypting %d: %v", c, err) } if bytes.Compare(td.data, expected[i]) != 0 { t.Errorf("expected %d to be encrypted to %d, but found %d", c, expected[i], td.data) } } }
func TranslateOIDFromCache(oid []int) (string, string, error) { if len(oid) < min_cache_prefix_oid_length { return "", "", fmt.Errorf("no prefix cache found which length less than %d", min_cache_prefix_oid_length) } for x := max_cache_prefix_oid_length; x >= min_cache_prefix_oid_length; x-- { if len(oid) < x { continue } prefix_oid := oid[:x] prefix_oid_s := asn1.ObjectIdentifier(prefix_oid).String() if v, ok := cache_prefix[prefix_oid_s]; ok == true { if suffix, err := translateSuffix(oid[x:len(oid)]); err == nil { return v, suffix, nil } else { fmt.Println("Error: ", oid) return v, "", err } } } return "", "", fmt.Errorf("didn't found oid in cache: %s", asn1.ObjectIdentifier(oid).String()) }
// addPolicies adds Certificate Policies and optional Policy Qualifiers to a // certificate, based on the input config. Go's x509 library allows setting // Certificate Policies easily, but does not support nested Policy Qualifiers // under those policies. So we need to construct the ASN.1 structure ourselves. func addPolicies(template *x509.Certificate, policies []config.CertificatePolicy) error { asn1PolicyList := []policyInformation{} for _, policy := range policies { pi := policyInformation{ // The PolicyIdentifier is an OID assigned to a given issuer. PolicyIdentifier: asn1.ObjectIdentifier(policy.ID), } switch policy.Type { case "id-qt-unotice": pi.UserNoticePolicyQualifiers = []userNoticePolicyQualifier{ userNoticePolicyQualifier{ PolicyQualifierID: iDQTUserNotice, Qualifier: userNotice{ ExplicitText: policy.Qualifier, }, }, } case "id-qt-cps": pi.PolicyQualifiers = []policyQualifier{ policyQualifier{ PolicyQualifierID: iDQTUserNotice, Qualifier: policy.Qualifier, }, } pi.PolicyQualifiers = []policyQualifier{ policyQualifier{ PolicyQualifierID: iDQTCertificationPracticeStatement, Qualifier: policy.Qualifier, }, } case "": // Empty qualifier type is fine: Include this Certificate Policy, but // don't include a Policy Qualifier. default: return errors.New("Invalid qualifier type in Policies " + policy.Type) } asn1PolicyList = append(asn1PolicyList, pi) } asn1Bytes, err := asn1.Marshal(asn1PolicyList) if err != nil { return err } template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{ Id: asn1.ObjectIdentifier{2, 5, 29, 32}, Critical: false, Value: asn1Bytes, }) return nil }
// UnmarshalJSON implements the json.Unmarshler interface func (s *SignatureAlgorithm) UnmarshalJSON(b []byte) error { var aux auxSignatureAlgorithm if err := json.Unmarshal(b, &aux); err != nil { return err } *s = UnknownSignatureAlgorithm oid := asn1.ObjectIdentifier(aux.OID.AsSlice()) for _, val := range signatureAlgorithmDetails { if val.oid.Equal(oid) { *s = val.algo break } } return nil }
func TestPbDecrypt(t *testing.T) { tests := [][]byte{ []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes []byte("\x35\x0c\xc0\x8d\xab\xa9\x5d\x30\x7f\x9a\xec\x6a\xd8\x9b\x9c\xd9"), // 9 padding bytes, incorrect []byte("\xb2\xf9\x6e\x06\x60\xae\x20\xcf\x08\xa0\x7b\xd9\x6b\x20\xef\x41"), // incorrect padding bytes: [ ... 0x04 0x02 ] } expected := []interface{}{ []byte("A secret!"), []byte("A secret"), ErrDecryption, ErrDecryption, } for i, c := range tests { td := testDecryptable{ data: c, algorithm: pkix.AlgorithmIdentifier{ Algorithm: asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}), // SHA1/3TDES Parameters: pbeParams{ Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"), Iterations: 4096, }.RawASN1(), }, } p, _ := bmpString([]byte("sesame")) m, err := pbDecrypt(td, p) switch e := expected[i].(type) { case []byte: if err != nil { t.Errorf("error decrypting C=%x: %v", c, err) } if bytes.Compare(m, e) != 0 { t.Errorf("expected C=%x to be decoded to M=%x, but found %x", c, e, m) } case error: if err == nil || err.Error() != e.Error() { t.Errorf("expecting error '%v' during decryption of c=%x, but found err='%v'", e, c, err) } } } }
func TestPbDecrypterFor(t *testing.T) { params, _ := asn1.Marshal(pbeParams{ Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, Iterations: 2048, }) alg := pkix.AlgorithmIdentifier{ Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), Parameters: asn1.RawValue{ FullBytes: params, }, } pass, _ := bmpString("Sesame open") _, _, err := pbDecrypterFor(alg, pass) if _, ok := err.(NotImplementedError); !ok { t.Errorf("expected not implemented error, got: %T %s", err, err) } alg.Algorithm = sha1WithTripleDES cbc, blockSize, err := pbDecrypterFor(alg, pass) if err != nil { t.Errorf("unexpected error from pbDecrypterFor %v", err) } if blockSize != 8 { t.Errorf("unexpected block size %d, wanted 8", blockSize) } plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8} expectedCiphertext := []byte{185, 73, 135, 249, 137, 1, 122, 247} ciphertext := make([]byte, len(plaintext)) cbc.CryptBlocks(ciphertext, plaintext) if bytes.Compare(ciphertext, expectedCiphertext) != 0 { t.Errorf("bad ciphertext, got %x but wanted %x", ciphertext, expectedCiphertext) } }
) type macData struct { Mac digestInfo MacSalt []byte Iterations int `asn1:"optional,default:1"` } // from PKCS#7: type digestInfo struct { Algorithm pkix.AlgorithmIdentifier Digest []byte } var ( oidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) ) func verifyMac(macData *macData, message, password []byte) error { if !macData.Mac.Algorithm.Algorithm.Equal(oidSHA1) { return NotImplementedError("unknown digest algorithm: " + macData.Mac.Algorithm.Algorithm.String()) } key := pbkdf(sha1Sum, 20, 64, macData.MacSalt, password, macData.Iterations, 3, 20) mac := hmac.New(sha1.New, key) mac.Write(message) expectedMAC := mac.Sum(nil) if !hmac.Equal(macData.Mac.Digest, expectedMAC) { return ErrIncorrectPassword
// Sign signs a new certificate based on the PEM-encoded client // certificate or certificate request with the signing profile, // specified by profileName. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { profile, err := signer.Profile(s, req.Profile) if err != nil { return } block, _ := pem.Decode([]byte(req.Request)) if block == nil { return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) } if block.Type != "CERTIFICATE REQUEST" { return nil, cferr.Wrap(cferr.CSRError, cferr.BadRequest, errors.New("not a certificate or csr")) } csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes) if err != nil { return nil, err } // Copy out only the fields from the CSR authorized by policy. safeTemplate := x509.Certificate{} // If the profile contains no explicit whitelist, assume that all fields // should be copied from the CSR. if profile.CSRWhitelist == nil { safeTemplate = *csrTemplate } else { if profile.CSRWhitelist.Subject { safeTemplate.Subject = csrTemplate.Subject } if profile.CSRWhitelist.PublicKeyAlgorithm { safeTemplate.PublicKeyAlgorithm = csrTemplate.PublicKeyAlgorithm } if profile.CSRWhitelist.PublicKey { safeTemplate.PublicKey = csrTemplate.PublicKey } if profile.CSRWhitelist.SignatureAlgorithm { safeTemplate.SignatureAlgorithm = csrTemplate.SignatureAlgorithm } if profile.CSRWhitelist.DNSNames { safeTemplate.DNSNames = csrTemplate.DNSNames } if profile.CSRWhitelist.IPAddresses { safeTemplate.IPAddresses = csrTemplate.IPAddresses } } OverrideHosts(&safeTemplate, req.Hosts) safeTemplate.Subject = PopulateSubjectFromCSR(req.Subject, safeTemplate.Subject) // If there is a whitelist, ensure that both the Common Name and SAN DNSNames match if profile.NameWhitelist != nil { if safeTemplate.Subject.CommonName != "" { if profile.NameWhitelist.Find([]byte(safeTemplate.Subject.CommonName)) == nil { return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } } for _, name := range safeTemplate.DNSNames { if profile.NameWhitelist.Find([]byte(name)) == nil { return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } } } if profile.ClientProvidesSerialNumbers { if req.Serial == nil { fmt.Printf("xx %#v\n", profile) return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial) } safeTemplate.SerialNumber = req.Serial } else { // RFC 5280 4.1.2.2: // Certificate users MUST be able to handle serialNumber // values up to 20 octets. Conforming CAs MUST NOT use // serialNumber values longer than 20 octets. // // If CFSSL is providing the serial numbers, it makes // sense to use the max supported size. serialNumber := make([]byte, 20) _, err = io.ReadFull(rand.Reader, serialNumber) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) } // SetBytes interprets buf as the bytes of a big-endian // unsigned integer. The leading byte should be masked // off to ensure it isn't negative. serialNumber[0] &= 0x7F safeTemplate.SerialNumber = new(big.Int).SetBytes(serialNumber) } if len(req.Extensions) > 0 { for _, ext := range req.Extensions { oid := asn1.ObjectIdentifier(ext.ID) if !profile.ExtensionWhitelist[oid.String()] { return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) } rawValue, err := hex.DecodeString(ext.Value) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.InvalidRequest, err) } safeTemplate.ExtraExtensions = append(safeTemplate.ExtraExtensions, pkix.Extension{ Id: oid, Critical: ext.Critical, Value: rawValue, }) } } var certTBS = safeTemplate if len(profile.CTLogServers) > 0 { // Add a poison extension which prevents validation var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}} var poisonedPreCert = certTBS poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension) cert, err = s.sign(&poisonedPreCert, profile) if err != nil { return } derCert, _ := pem.Decode(cert) prechain := []ct.ASN1Cert{derCert.Bytes, s.ca.Raw} var sctList []ct.SignedCertificateTimestamp for _, server := range profile.CTLogServers { log.Infof("submitting poisoned precertificate to %s", server) var ctclient = client.New(server) var resp *ct.SignedCertificateTimestamp resp, err = ctclient.AddPreChain(prechain) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.PrecertSubmissionFailed, err) } sctList = append(sctList, *resp) } var serializedSCTList []byte serializedSCTList, err = serializeSCTList(sctList) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) } // Serialize again as an octet string before embedding serializedSCTList, err = asn1.Marshal(serializedSCTList) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) } var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList} certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension) } var signedCert []byte signedCert, err = s.sign(&certTBS, profile) if err != nil { return nil, err } if s.db != nil { var certRecord = &certdb.CertificateRecord{ Serial: certTBS.SerialNumber.String(), CALabel: req.Label, Status: "good", Expiry: certTBS.NotAfter, PEM: string(signedCert), } err = certdb.InsertCertificate(s.db, certRecord) if err != nil { return nil, err } log.Debug("saved certificate with serial number ", certTBS.SerialNumber) } return signedCert, nil }
"crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/rsa" "crypto/sha1" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "errors" "math/big" "strconv" "time" ) var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) // ResponseStatus contains the result of an OCSP request. See // https://tools.ietf.org/html/rfc6960#section-2.3 type ResponseStatus int const ( Success ResponseStatus = 0 Malformed ResponseStatus = 1 InternalError ResponseStatus = 2 TryLater ResponseStatus = 3 // Status code four is unused in OCSP. See // https://tools.ietf.org/html/rfc6960#section-4.2.1 SignatureRequired ResponseStatus = 5 Unauthorized ResponseStatus = 6 )
// MarshalJSON marshals an oid into a JSON string. func (oid OID) MarshalJSON() ([]byte, error) { return []byte(fmt.Sprintf(`"%v"`, asn1.ObjectIdentifier(oid))), nil }
func (bin *Binary) RemoveAppendedTag() (contents []byte, err error) { if _, ok := bin.AppendedTag(); !ok { return nil, errors.New("authenticodetag: no appended tag found") } return bin.buildBinary(bin.asn1Data, nil), nil } func (bin *Binary) SetAppendedTag(tagContents []byte) (contents []byte, err error) { return bin.buildBinary(bin.asn1Data, tagContents), nil } // oidChromeTag is an OID that we use for the extension in the superfluous // certificate. It's in the Google arc, but not officially assigned. var oidChromeTag = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 11129, 2, 1, 9999}) func (bin *Binary) getSuperfluousCert() (cert *x509.Certificate, err error) { n := len(bin.signedData.PKCS7.Certs) if n == 0 { return nil, nil } if cert, err = x509.ParseCertificate(bin.signedData.PKCS7.Certs[n-1].FullBytes); err != nil { return nil, err } for _, ext := range cert.Extensions { if !ext.Critical && ext.Id.Equal(oidChromeTag) { return cert, nil }
// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pkcs12 import ( "bytes" "crypto/x509/pkix" "encoding/asn1" "testing" ) var sha1WithTripleDES = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) func TestPbDecrypterFor(t *testing.T) { params, _ := asn1.Marshal(pbeParams{ Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, Iterations: 2048, }) alg := pkix.AlgorithmIdentifier{ Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), Parameters: asn1.RawValue{ FullBytes: params, }, } pass, _ := bmpString("Sesame open") _, _, err := pbDecrypterFor(alg, pass) if _, ok := err.(NotImplementedError); !ok {
// populate is used to fill in the fields that are not in JSON // // First, the ExpiryString parameter is needed to parse // expiration timestamps from JSON. The JSON decoder is not able to // decode a string time duration to a time.Duration, so this is called // when loading the configuration to properly parse and fill out the // Expiry parameter. // This function is also used to create references to the auth key // and default remote for the profile. // It returns true if ExpiryString is a valid representation of a // time.Duration, and the AuthKeyString and RemoteName point to // valid objects. It returns false otherwise. func (p *SigningProfile) populate(cfg *Config) error { if p == nil { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("can't parse nil profile")) } var err error if p.RemoteName == "" && p.AuthRemote.RemoteName == "" { log.Debugf("parse expiry in profile") if p.ExpiryString == "" { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("empty expiry string")) } dur, err := time.ParseDuration(p.ExpiryString) if err != nil { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) } log.Debugf("expiry is valid") p.Expiry = dur if p.BackdateString != "" { dur, err = time.ParseDuration(p.BackdateString) if err != nil { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) } p.Backdate = dur } if !p.NotBefore.IsZero() && !p.NotAfter.IsZero() && p.NotAfter.Before(p.NotBefore) { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) } if len(p.Policies) > 0 { for _, policy := range p.Policies { for _, qualifier := range policy.Qualifiers { if qualifier.Type != "" && qualifier.Type != "id-qt-unotice" && qualifier.Type != "id-qt-cps" { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("invalid policy qualifier type")) } } } } } else if p.RemoteName != "" { log.Debug("match remote in profile to remotes section") if p.AuthRemote.RemoteName != "" { log.Error("profile has both a remote and an auth remote specified") return cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } if remote := cfg.Remotes[p.RemoteName]; remote != "" { if err := p.updateRemote(remote); err != nil { return err } } else { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to find remote in remotes section")) } } else { log.Debug("match auth remote in profile to remotes section") if remote := cfg.Remotes[p.AuthRemote.RemoteName]; remote != "" { if err := p.updateRemote(remote); err != nil { return err } } else { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to find remote in remotes section")) } } if p.AuthKeyName != "" { log.Debug("match auth key in profile to auth_keys section") if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true { if key.Type == "standard" { p.Provider, err = auth.New(key.Key, nil) if err != nil { log.Debugf("failed to create new standard auth provider: %v", err) return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to create new standard auth provider")) } } else { log.Debugf("unknown authentication type %v", key.Type) return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("unknown authentication type")) } } else { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to find auth_key in auth_keys section")) } } if p.AuthRemote.AuthKeyName != "" { log.Debug("match auth remote key in profile to auth_keys section") if key, ok := cfg.AuthKeys[p.AuthRemote.AuthKeyName]; ok == true { if key.Type == "standard" { p.RemoteProvider, err = auth.New(key.Key, nil) if err != nil { log.Debugf("failed to create new standard auth provider: %v", err) return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to create new standard auth provider")) } } else { log.Debugf("unknown authentication type %v", key.Type) return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("unknown authentication type")) } } else { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to find auth_remote's auth_key in auth_keys section")) } } if p.NameWhitelistString != "" { log.Debug("compiling whitelist regular expression") rule, err := regexp.Compile(p.NameWhitelistString) if err != nil { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("failed to compile name whitelist section")) } p.NameWhitelist = rule } p.ExtensionWhitelist = map[string]bool{} for _, oid := range p.AllowedExtensions { p.ExtensionWhitelist[asn1.ObjectIdentifier(oid).String()] = true } return nil }
// Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses // are signed messages attesting to the validity of a certificate for a small // period of time. This is used to manage revocation for X.509 certificates. package ocsp import ( "crypto" "crypto/rsa" _ "crypto/sha1" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "time" ) var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) var idSHA1WithRSA = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 1, 5}) // These are internal structures that reflect the ASN.1 structure of an OCSP // response. See RFC 2560, section 4.2. const ( ocspSuccess = 0 ocspMalformed = 1 ocspInternalError = 2 ocspTryLater = 3 ocspSigRequired = 4 ocspUnauthorized = 5 ) type certID struct {
package pkcs12 import ( "bytes" "crypto/cipher" "crypto/des" "crypto/x509/pkix" "encoding/asn1" "errors" "github.com/joonakannisto/gocrypto/pkcs12/internal/rc2" ) var ( oidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) oidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6}) ) // pbeCipher is an abstraction of a PKCS#12 cipher. type pbeCipher interface { // create returns a cipher.Block given a key. create(key []byte) (cipher.Block, error) // deriveKey returns a key derived from the given password and salt. deriveKey(salt, password []byte, iterations int) []byte // deriveKey returns an IV derived from the given password and salt. deriveIV(salt, password []byte, iterations int) []byte } type shaWithTripleDESCBC struct{}
* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package pkcs7 import ( "crypto/x509" "encoding/asn1" "fmt" ) var signedDataIdentifier = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 2}) // SignedDataEnvelope represents a wrapped SignedData // object found in PEM-encoded PKCS7 blocks. type SignedDataEnvelope struct { Raw asn1.RawContent Type asn1.ObjectIdentifier SignedData SignedData `asn1:"tag:0,explicit,optional"` } // SignedData contains signed data and related info. // Refer to RFC 2315, Section 9.1 for definition of this type. type SignedData struct { Version int DigestAlgorithms []asn1.ObjectIdentifier `asn1:"set"` ContentInfo asn1.RawValue
// certificates and keys for use with the crypto/tls package. package pkcs12 import ( "crypto/ecdsa" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "encoding/hex" "encoding/pem" "errors" ) var ( oidDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 1}) oidEncryptedDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 6}) oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20}) oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21}) oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1}) ) type pfxPdu struct { Version int AuthSafe contentInfo MacData macData `asn1:"optional"` } type contentInfo struct { ContentType asn1.ObjectIdentifier
// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pkcs12 import ( "crypto/rand" "crypto/x509" "encoding/asn1" "errors" ) var ( // see https://tools.ietf.org/html/rfc7292#appendix-D oidCertTypeX509Certificate = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 22, 1}) oidPKCS8ShroundedKeyBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 2}) oidCertBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 3}) ) type certBag struct { Id asn1.ObjectIdentifier Data []byte `asn1:"tag:0,explicit"` } func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{}, err error) { pkinfo := new(encryptedPrivateKeyInfo) if err = unmarshal(asn1Data, pkinfo); err != nil { return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error()) }
// Sign signs a new certificate based on the PEM-encoded client // certificate or certificate request with the signing profile, // specified by profileName. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { profile, err := signer.Profile(s, req.Profile) if err != nil { return } block, _ := pem.Decode([]byte(req.Request)) if block == nil { return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) } if block.Type != "CERTIFICATE REQUEST" { return nil, cferr.Wrap(cferr.CSRError, cferr.BadRequest, errors.New("not a certificate or csr")) } csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes) if err != nil { return nil, err } // Copy out only the fields from the CSR authorized by policy. safeTemplate := x509.Certificate{} // If the profile contains no explicit whitelist, assume that all fields // should be copied from the CSR. if profile.CSRWhitelist == nil { safeTemplate = *csrTemplate } else { if profile.CSRWhitelist.Subject { safeTemplate.Subject = csrTemplate.Subject } if profile.CSRWhitelist.PublicKeyAlgorithm { safeTemplate.PublicKeyAlgorithm = csrTemplate.PublicKeyAlgorithm } if profile.CSRWhitelist.PublicKey { safeTemplate.PublicKey = csrTemplate.PublicKey } if profile.CSRWhitelist.SignatureAlgorithm { safeTemplate.SignatureAlgorithm = csrTemplate.SignatureAlgorithm } if profile.CSRWhitelist.DNSNames { safeTemplate.DNSNames = csrTemplate.DNSNames } if profile.CSRWhitelist.IPAddresses { safeTemplate.IPAddresses = csrTemplate.IPAddresses } } OverrideHosts(&safeTemplate, req.Hosts) safeTemplate.Subject = PopulateSubjectFromCSR(req.Subject, safeTemplate.Subject) // If there is a whitelist, ensure that both the Common Name and SAN DNSNames match if profile.NameWhitelist != nil { if safeTemplate.Subject.CommonName != "" { if profile.NameWhitelist.Find([]byte(safeTemplate.Subject.CommonName)) == nil { return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } } for _, name := range safeTemplate.DNSNames { if profile.NameWhitelist.Find([]byte(name)) == nil { return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } } } if profile.ClientProvidesSerialNumbers { if req.Serial == nil { fmt.Printf("xx %#v\n", profile) return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial) } safeTemplate.SerialNumber = req.Serial } else { serialNumber, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) } safeTemplate.SerialNumber = serialNumber } if len(req.Extensions) > 0 { for _, ext := range req.Extensions { oid := asn1.ObjectIdentifier(ext.ID) if !profile.ExtensionWhitelist[oid.String()] { return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) } rawValue, err := hex.DecodeString(ext.Value) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.InvalidRequest, err) } safeTemplate.ExtraExtensions = append(safeTemplate.ExtraExtensions, pkix.Extension{ Id: oid, Critical: ext.Critical, Value: rawValue, }) } } var certTBS = safeTemplate if len(profile.CTLogServers) > 0 { // Add a poison extension which prevents validation var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}} var poisonedPreCert = certTBS poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension) cert, err = s.sign(&poisonedPreCert, profile) if err != nil { return } derCert, _ := pem.Decode(cert) prechain := []ct.ASN1Cert{derCert.Bytes, s.ca.Raw} var sctList []ct.SignedCertificateTimestamp for _, server := range profile.CTLogServers { log.Infof("submitting poisoned precertificate to %s", server) var ctclient = client.New(server) var resp *ct.SignedCertificateTimestamp resp, err = ctclient.AddPreChain(prechain) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.PrecertSubmissionFailed, err) } sctList = append(sctList, *resp) } var serializedSCTList []byte serializedSCTList, err = serializeSCTList(sctList) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) } // Serialize again as an octet string before embedding serializedSCTList, err = asn1.Marshal(serializedSCTList) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) } var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList} certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension) } return s.sign(&certTBS, profile) }
// Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses // are signed messages attesting to the validity of a certificate for a small // period of time. This is used to manage revocation for X.509 certificates. package ocsp import ( "crypto" _ "crypto/sha1" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "math/big" "time" ) var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) // These are internal structures that reflect the ASN.1 structure of an OCSP // response. See RFC 2560, section 4.2. const ( ocspSuccess = 0 ocspMalformed = 1 ocspInternalError = 2 ocspTryLater = 3 ocspSigRequired = 4 ocspUnauthorized = 5 ) struct certID { HashAlgorithm pkix.AlgorithmIdentifier