// countCertificatesByNames returns, for a single domain, the count of
// certificates issued in the given time range for that domain and its
// subdomains.
// The highest count this function can return is 10,000. If there are more
// certificates than that matching one of the provided domain names, it will return
// TooManyCertificatesError.
func (ssa *SQLStorageAuthority) countCertificatesByName(domain string, earliest, latest time.Time) (int, error) {
	var count int64
	const max = 10000
	var serials []struct {
		Serial string
	}
	_, err := ssa.dbMap.Select(
		&serials,
		`SELECT serial from issuedNames
		 WHERE (reversedName = :reversedDomain OR
			      reversedName LIKE CONCAT(:reversedDomain, ".%"))
		 AND notBefore > :earliest AND notBefore <= :latest
		 LIMIT :limit;`,
		map[string]interface{}{
			"reversedDomain": core.ReverseName(domain),
			"earliest":       earliest,
			"latest":         latest,
			"limit":          max + 1,
		})
	if err == sql.ErrNoRows {
		return 0, nil
	} else if err != nil {
		return -1, err
	} else if count > max {
		return max, TooManyCertificatesError(fmt.Sprintf("More than %d issuedName entries for %s.", max, domain))
	}
	serialMap := make(map[string]struct{}, len(serials))
	for _, s := range serials {
		serialMap[s.Serial] = struct{}{}
	}

	return len(serialMap), nil
}
// LoadRules loads the whitelist and blacklist into the database in a transaction
// deleting any previous content
func (padb *PolicyAuthorityDatabaseImpl) LoadRules(rs RuleSet) error {
	tx, err := padb.dbMap.Begin()
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = tx.Exec("DELETE FROM blacklist")
	if err != nil {
		tx.Rollback()
		return err
	}
	for _, r := range rs.Blacklist {
		r.Host = core.ReverseName(r.Host)
		tx.Insert(&r)
	}
	_, err = tx.Exec("DELETE FROM whitelist")
	if err != nil {
		tx.Rollback()
		return err
	}
	for _, r := range rs.Whitelist {
		tx.Insert(&r)
	}

	err = tx.Commit()
	return err
}
Beispiel #3
0
func addIssuedNames(tx execable, cert *x509.Certificate) error {
	var qmarks []string
	var values []interface{}
	for _, name := range cert.DNSNames {
		values = append(values,
			core.ReverseName(name),
			core.SerialToString(cert.SerialNumber),
			cert.NotBefore)
		qmarks = append(qmarks, "(?, ?, ?)")
	}
	query := `INSERT INTO issuedNames (reversedName, serial, notBefore) VALUES ` + strings.Join(qmarks, ", ") + `;`
	_, err := tx.Exec(query, values...)
	return err
}
// CheckHostLists will query the database for white/blacklist rules that match host,
// if both whitelist and blacklist rules are found the blacklist will always win
func (padb *PolicyAuthorityDatabaseImpl) CheckHostLists(host string, requireWhitelisted bool) error {
	if requireWhitelisted {
		if !padb.allowedByWhitelist(host) {
			// return fmt.Errorf("Domain is not whitelisted for issuance")
			return ErrNotWhitelisted
		}
	}
	// Overrides the whitelist if a blacklist rule is found
	host = core.ReverseName(host)
	if !padb.allowedByBlacklist(host) {
		// return fmt.Errorf("Domain is blacklisted for issuance")
		return ErrBlacklisted
	}
	return nil
}
// DumpRules retrieves all domainRules in the database so they can be written to
// disk
func (padb *PolicyAuthorityDatabaseImpl) DumpRules() (rs RuleSet, err error) {
	var bList []BlacklistRule
	_, err = padb.dbMap.Select(&bList, "SELECT * FROM blacklist")
	if err != nil {
		return
	}
	for _, r := range bList {
		r.Host = core.ReverseName(r.Host)
		rs.Blacklist = append(rs.Blacklist, r)
	}
	var wList []WhitelistRule
	_, err = padb.dbMap.Select(&wList, "SELECT * FROM whitelist")
	if err != nil {
		return
	}
	rs.Whitelist = wList
	return rs, err
}
// AddCertificate stores an issued certificate.
func (ssa *SQLStorageAuthority) AddCertificate(certDER []byte, regID int64) (digest string, err error) {
	var parsedCertificate *x509.Certificate
	parsedCertificate, err = x509.ParseCertificate(certDER)
	if err != nil {
		return
	}
	digest = core.Fingerprint256(certDER)
	serial := core.SerialToString(parsedCertificate.SerialNumber)

	cert := &core.Certificate{
		RegistrationID: regID,
		Serial:         serial,
		Digest:         digest,
		DER:            certDER,
		Issued:         ssa.clk.Now(),
		Expires:        parsedCertificate.NotAfter,
	}
	certStatus := &core.CertificateStatus{
		SubscriberApproved: false,
		Status:             core.OCSPStatus("good"),
		OCSPLastUpdated:    time.Time{},
		OCSPResponse:       []byte{},
		Serial:             serial,
		RevokedDate:        time.Time{},
		RevokedReason:      0,
		LockCol:            0,
	}
	issuedNames := make([]issuedNameModel, len(parsedCertificate.DNSNames))
	for i, name := range parsedCertificate.DNSNames {
		issuedNames[i] = issuedNameModel{
			ReversedName: core.ReverseName(name),
			Serial:       serial,
			NotBefore:    parsedCertificate.NotBefore,
		}
	}

	tx, err := ssa.dbMap.Begin()
	if err != nil {
		return
	}

	// TODO Verify that the serial number doesn't yet exist
	err = tx.Insert(cert)
	if err != nil {
		tx.Rollback()
		return
	}

	err = tx.Insert(certStatus)
	if err != nil {
		tx.Rollback()
		return
	}

	for _, issuedName := range issuedNames {
		err = tx.Insert(&issuedName)
		if err != nil {
			tx.Rollback()
			return
		}
	}

	err = tx.Commit()
	return
}