This commit is contained in:
parent
cd29ec9eb0
commit
99689080de
269
services/caa.go
Normal file
269
services/caa.go
Normal file
|
@ -0,0 +1,269 @@
|
|||
// Copyright or © or Copr. happyDNS (2023)
|
||||
//
|
||||
// contact@happydomain.org
|
||||
//
|
||||
// This software is a computer program whose purpose is to provide a modern
|
||||
// interface to interact with DNS systems.
|
||||
//
|
||||
// This software is governed by the CeCILL license under French law and abiding
|
||||
// by the rules of distribution of free software. You can use, modify and/or
|
||||
// redistribute the software under the terms of the CeCILL license as
|
||||
// circulated by CEA, CNRS and INRIA at the following URL
|
||||
// "http://www.cecill.info".
|
||||
//
|
||||
// As a counterpart to the access to the source code and rights to copy, modify
|
||||
// and redistribute granted by the license, users are provided only with a
|
||||
// limited warranty and the software's author, the holder of the economic
|
||||
// rights, and the successive licensors have only limited liability.
|
||||
//
|
||||
// In this respect, the user's attention is drawn to the risks associated with
|
||||
// loading, using, modifying and/or developing or reproducing the software by
|
||||
// the user in light of its specific status of free software, that may mean
|
||||
// that it is complicated to manipulate, and that also therefore means that it
|
||||
// is reserved for developers and experienced professionals having in-depth
|
||||
// computer knowledge. Users are therefore encouraged to load and test the
|
||||
// software's suitability as regards their requirements in conditions enabling
|
||||
// the security of their systems and/or data to be ensured and, more generally,
|
||||
// to use and operate it in the same conditions as regards security.
|
||||
//
|
||||
// The fact that you are presently reading this means that you have had
|
||||
// knowledge of the CeCILL license and that you accept its terms.
|
||||
|
||||
package svcs
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
"git.happydns.org/happyDomain/services/common"
|
||||
"git.happydns.org/happyDomain/utils"
|
||||
)
|
||||
|
||||
type CAAParameter struct {
|
||||
Tag string
|
||||
Value string
|
||||
}
|
||||
|
||||
type CAAIssueValue struct {
|
||||
IssuerDomainName string
|
||||
Parameters []CAAParameter
|
||||
}
|
||||
|
||||
func parseIssueValue(value string) (ret CAAIssueValue) {
|
||||
tmp := strings.Split(value, ";")
|
||||
ret.IssuerDomainName = strings.TrimSpace(tmp[0])
|
||||
|
||||
for _, param := range tmp[1:] {
|
||||
tmpparam := strings.SplitN(param, "=", 2)
|
||||
ret.Parameters = append(ret.Parameters, CAAParameter{
|
||||
Tag: strings.TrimSpace(tmpparam[0]),
|
||||
Value: strings.TrimSpace(tmpparam[1]),
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (v *CAAIssueValue) String() string {
|
||||
var b strings.Builder
|
||||
|
||||
b.WriteString(v.IssuerDomainName)
|
||||
|
||||
if len(v.Parameters) > 0 {
|
||||
b.WriteString(";")
|
||||
|
||||
for _, param := range v.Parameters {
|
||||
b.WriteString(param.Tag)
|
||||
b.WriteString("=")
|
||||
b.WriteString(param.Value)
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
type CAA struct {
|
||||
DisallowIssue bool
|
||||
Issue []CAAIssueValue
|
||||
DisallowWildcardIssue bool
|
||||
IssueWild []CAAIssueValue
|
||||
Iodef []*common.URL
|
||||
}
|
||||
|
||||
func (s *CAA) GetNbResources() int {
|
||||
nb := 0
|
||||
|
||||
if s.DisallowIssue {
|
||||
nb += 1
|
||||
} else {
|
||||
nb += len(s.Issue)
|
||||
if s.DisallowWildcardIssue {
|
||||
nb += 1
|
||||
} else {
|
||||
nb += len(s.IssueWild)
|
||||
}
|
||||
}
|
||||
|
||||
return nb + len(s.Iodef)
|
||||
}
|
||||
|
||||
func (s *CAA) GenComment(origin string) string {
|
||||
if s.DisallowIssue {
|
||||
return "Certificate issuance disallowed"
|
||||
} else {
|
||||
var issuance []string
|
||||
for _, iss := range s.Issue {
|
||||
issuance = append(issuance, iss.IssuerDomainName)
|
||||
}
|
||||
|
||||
ret := strings.Join(issuance, ", ")
|
||||
|
||||
if s.DisallowWildcardIssue {
|
||||
if ret != "" {
|
||||
ret += "; "
|
||||
}
|
||||
ret += "Wildcard issuance disallowed"
|
||||
} else if len(s.IssueWild) > 0 {
|
||||
if ret != "" {
|
||||
ret += "; wildcard: "
|
||||
}
|
||||
|
||||
var issuancew []string
|
||||
for _, iss := range s.IssueWild {
|
||||
issuancew = append(issuancew, iss.IssuerDomainName)
|
||||
}
|
||||
|
||||
ret += strings.Join(issuancew, ", ")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CAA) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if s.DisallowIssue {
|
||||
rc := utils.NewRecordConfig(domain, "CAA", ttl, origin)
|
||||
rc.CaaFlag = 0
|
||||
rc.CaaTag = "issue"
|
||||
rc.SetTarget(";")
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
} else {
|
||||
for _, issue := range s.Issue {
|
||||
rc := utils.NewRecordConfig(domain, "CAA", ttl, origin)
|
||||
rc.CaaFlag = 0
|
||||
rc.CaaTag = "issue"
|
||||
rc.SetTarget(issue.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
if s.DisallowWildcardIssue {
|
||||
rc := utils.NewRecordConfig(domain, "CAA", ttl, origin)
|
||||
rc.CaaFlag = 0
|
||||
rc.CaaTag = "issuewild"
|
||||
rc.SetTarget(";")
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
} else {
|
||||
for _, issue := range s.IssueWild {
|
||||
rc := utils.NewRecordConfig(domain, "CAA", ttl, origin)
|
||||
rc.CaaFlag = 0
|
||||
rc.CaaTag = "issuewild"
|
||||
rc.SetTarget(issue.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.Iodef) > 0 {
|
||||
for _, iodef := range s.Iodef {
|
||||
rc := utils.NewRecordConfig(domain, "CAA", ttl, origin)
|
||||
rc.CaaFlag = 0
|
||||
rc.CaaTag = "iodef"
|
||||
rc.SetTarget(iodef.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func caa_analyze(a *Analyzer) (err error) {
|
||||
pool := map[string]*CAA{}
|
||||
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeCAA}) {
|
||||
domain := record.NameFQDN
|
||||
|
||||
if record.Type == "CAA" {
|
||||
if _, ok := pool[domain]; !ok {
|
||||
pool[domain] = &CAA{}
|
||||
}
|
||||
|
||||
analyzed := pool[domain]
|
||||
|
||||
if record.CaaTag == "issue" {
|
||||
value := record.GetTargetField()
|
||||
if value == ";" {
|
||||
analyzed.DisallowIssue = true
|
||||
} else {
|
||||
analyzed.Issue = append(analyzed.Issue, parseIssueValue(value))
|
||||
}
|
||||
}
|
||||
|
||||
if record.CaaTag == "issuewild" {
|
||||
value := record.GetTargetField()
|
||||
if value == ";" {
|
||||
analyzed.DisallowWildcardIssue = true
|
||||
} else {
|
||||
analyzed.IssueWild = append(analyzed.IssueWild, parseIssueValue(value))
|
||||
}
|
||||
}
|
||||
|
||||
if record.CaaTag == "iodef" {
|
||||
if u, err := url.Parse(record.GetTargetField()); err != nil {
|
||||
continue
|
||||
} else {
|
||||
tmp := common.URL(*u)
|
||||
analyzed.Iodef = append(analyzed.Iodef, &tmp)
|
||||
}
|
||||
}
|
||||
|
||||
err = a.UseRR(record, domain, pool[domain])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterService(
|
||||
func() happydns.Service {
|
||||
return &CAA{}
|
||||
},
|
||||
caa_analyze,
|
||||
ServiceInfos{
|
||||
Name: "Certification Authority Authorization (CAA)",
|
||||
Description: "Indicate to certificate authorities whether they are authorized to issue digital certificates for a particular domain name.",
|
||||
Categories: []string{
|
||||
"tls",
|
||||
},
|
||||
Restrictions: ServiceRestrictions{
|
||||
Single: true,
|
||||
NeedTypes: []uint16{
|
||||
dns.TypeCAA,
|
||||
},
|
||||
},
|
||||
},
|
||||
1,
|
||||
)
|
||||
}
|
59
services/common/url.go
Normal file
59
services/common/url.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright or © or Copr. happyDNS (2023)
|
||||
//
|
||||
// contact@happydomain.org
|
||||
//
|
||||
// This software is a computer program whose purpose is to provide a modern
|
||||
// interface to interact with DNS systems.
|
||||
//
|
||||
// This software is governed by the CeCILL license under French law and abiding
|
||||
// by the rules of distribution of free software. You can use, modify and/or
|
||||
// redistribute the software under the terms of the CeCILL license as
|
||||
// circulated by CEA, CNRS and INRIA at the following URL
|
||||
// "http://www.cecill.info".
|
||||
//
|
||||
// As a counterpart to the access to the source code and rights to copy, modify
|
||||
// and redistribute granted by the license, users are provided only with a
|
||||
// limited warranty and the software's author, the holder of the economic
|
||||
// rights, and the successive licensors have only limited liability.
|
||||
//
|
||||
// In this respect, the user's attention is drawn to the risks associated with
|
||||
// loading, using, modifying and/or developing or reproducing the software by
|
||||
// the user in light of its specific status of free software, that may mean
|
||||
// that it is complicated to manipulate, and that also therefore means that it
|
||||
// is reserved for developers and experienced professionals having in-depth
|
||||
// computer knowledge. Users are therefore encouraged to load and test the
|
||||
// software's suitability as regards their requirements in conditions enabling
|
||||
// the security of their systems and/or data to be ensured and, more generally,
|
||||
// to use and operate it in the same conditions as regards security.
|
||||
//
|
||||
// The fact that you are presently reading this means that you have had
|
||||
// knowledge of the CeCILL license and that you accept its terms.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type URL url.URL
|
||||
|
||||
func (u URL) String() string {
|
||||
tmp := url.URL(u)
|
||||
return (&tmp).String()
|
||||
}
|
||||
|
||||
func (u URL) MarshalJSON() ([]byte, error) {
|
||||
tmp := url.URL(u)
|
||||
return json.Marshal((&tmp).String())
|
||||
}
|
||||
|
||||
func (u *URL) UnmarshalJSON(b []byte) error {
|
||||
var v string
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
tmp, err := url.Parse(v)
|
||||
*u = URL(*tmp)
|
||||
return err
|
||||
}
|
|
@ -10,7 +10,7 @@ export async function listServiceSpecs(): Promise<Record<string, ServiceInfos>>
|
|||
}
|
||||
|
||||
export async function getServiceSpec(ssid: string): Promise<ServiceSpec> {
|
||||
if (ssid == "string") {
|
||||
if (ssid == "string" || ssid == "common.URL") {
|
||||
return Promise.resolve(<ServiceSpec>{fields: null});
|
||||
} else {
|
||||
const res = await fetch(`/api/service_specs/` + ssid, {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import BasicInput from '$lib/components/resources/basic.svelte';
|
||||
import CAAForm from '$lib/components/resources/CAA.svelte';
|
||||
import MapInput from '$lib/components/resources/map.svelte';
|
||||
import ObjectInput from '$lib/components/resources/object.svelte';
|
||||
import RawInput from '$lib/components/resources/raw.svelte';
|
||||
|
@ -45,6 +46,16 @@
|
|||
type={sanitizeType(type)}
|
||||
bind:value={value}
|
||||
/>
|
||||
{:else if type == "svcs.CAA"}
|
||||
<CAAForm
|
||||
edit={edit || editToolbar}
|
||||
{index}
|
||||
{readonly}
|
||||
{specs}
|
||||
bind:value={value}
|
||||
on:delete-this-service={(event) => dispatch("delete-this-service", event.detail)}
|
||||
on:update-this-service={(event) => dispatch("update-this-service", event.detail)}
|
||||
/>
|
||||
{:else if typeof value === 'object' || Array.isArray(specs)}
|
||||
<ObjectInput
|
||||
{edit}
|
||||
|
|
68
ui/src/lib/components/resources/CAA-iodef.svelte
Normal file
68
ui/src/lib/components/resources/CAA-iodef.svelte
Normal file
|
@ -0,0 +1,68 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
Input,
|
||||
} from 'sveltestrap';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let newone = false;
|
||||
export let readonly = false;
|
||||
export let value: any;
|
||||
|
||||
let kind: string = "web";
|
||||
let url: string;
|
||||
|
||||
$: if (value) switch (value.split(":")[0]) {
|
||||
case "mailto":
|
||||
kind = "mail";
|
||||
url = value.split(":")[1];
|
||||
break;
|
||||
default:
|
||||
kind = "web";
|
||||
url = value;
|
||||
}
|
||||
|
||||
function updateValue(url) {
|
||||
if (kind == "mail") {
|
||||
value = "mailto:" + url;
|
||||
} else {
|
||||
value = url;
|
||||
}
|
||||
}
|
||||
|
||||
$: updateValue(url);
|
||||
</script>
|
||||
|
||||
<div class="d-flex gap-2 mb-2">
|
||||
<Input type="select" bind:value={kind}>
|
||||
<option value="mail">Mail</option>
|
||||
<option value="web">Webhook</option>
|
||||
</Input>
|
||||
|
||||
<Input type={kind == "mail" ? "email" : "text"} bind:value={url} />
|
||||
|
||||
{#if !newone}
|
||||
<Button
|
||||
type="button"
|
||||
color="danger"
|
||||
outline
|
||||
on:click={() => dispatch("delete-iodef")}
|
||||
>
|
||||
<Icon name="trash" />
|
||||
</Button>
|
||||
{:else}
|
||||
<Button
|
||||
color="success"
|
||||
outline
|
||||
type="button"
|
||||
disabled={!value}
|
||||
on:click={() => {dispatch("add-iodef", value); value = { }}}
|
||||
>
|
||||
<Icon name="plus" />
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
106
ui/src/lib/components/resources/CAA-issuer.svelte
Normal file
106
ui/src/lib/components/resources/CAA-issuer.svelte
Normal file
|
@ -0,0 +1,106 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
FormGroup,
|
||||
Icon,
|
||||
Input,
|
||||
} from 'sveltestrap';
|
||||
|
||||
import { issuers, rev_issuers } from './CAA-issuers';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let edit = false;
|
||||
export let index: string;
|
||||
export let newone = false;
|
||||
export let readonly = false;
|
||||
export let value: any;
|
||||
|
||||
$: if (!value) value = { };
|
||||
</script>
|
||||
|
||||
<div class="d-flex gap-2 mb-2">
|
||||
{#if (newone && value.IssuerDomainName == "") || rev_issuers[value.IssuerDomainName]}
|
||||
<Input type="select" name="select" id="exampleSelect" readonly={readonly} bind:value={value.IssuerDomainName}>
|
||||
{#each Object.keys(issuers) as issuer}
|
||||
<option value={issuers[issuer][0]}>{issuer}</option>
|
||||
{/each}
|
||||
<option value={" "}>Autre</option>
|
||||
</Input>
|
||||
{:else}
|
||||
<Input type="text" bind:value={value.IssuerDomainName} />
|
||||
{/if}
|
||||
{#if !newone}
|
||||
<Button
|
||||
type="button"
|
||||
color="danger"
|
||||
outline
|
||||
on:click={() => dispatch("delete-issuer")}
|
||||
>
|
||||
<Icon name="trash" />
|
||||
</Button>
|
||||
{:else}
|
||||
<Button
|
||||
color="success"
|
||||
outline
|
||||
type="button"
|
||||
disabled={!value}
|
||||
on:click={() => {dispatch("add-issuer", value); value = { }}}
|
||||
>
|
||||
<Icon name="plus" />
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if !newone}
|
||||
<div class="d-flex align-items-center">
|
||||
{#if value.Parameters}
|
||||
{#each value.Parameters as parameter, k}
|
||||
<Badge color="info" class="me-1">
|
||||
{#if parameter.edit}
|
||||
<form
|
||||
class="d-flex align-items-center gap-1"
|
||||
on:submit|preventDefault={() => parameter.edit = false}
|
||||
>
|
||||
<Input size="sm" placeholder="key" bind:value={parameter.Tag} />
|
||||
=
|
||||
<Input size="sm" placeholder="value" bind:value={parameter.Value} />
|
||||
<Button
|
||||
type="submit"
|
||||
color="success"
|
||||
size="sm"
|
||||
>
|
||||
<Icon
|
||||
name="check"
|
||||
/>
|
||||
</Button>
|
||||
</form>
|
||||
{:else}
|
||||
<span
|
||||
on:dblclick={() => parameter.edit = true}
|
||||
>
|
||||
{parameter.Tag}={parameter.Value}
|
||||
</span>
|
||||
<span
|
||||
role="button"
|
||||
on:click={() => {value.Parameters.splice(k, 1); value = value;}}
|
||||
>
|
||||
<Icon
|
||||
name="x-circle-fill"
|
||||
/>
|
||||
</span>
|
||||
{/if}
|
||||
</Badge>
|
||||
{/each}
|
||||
{/if}
|
||||
<span
|
||||
class="badge bg-primary"
|
||||
role="button"
|
||||
on:click={() => {if (value.Parameters == null) value.Parameters = []; value.Parameters.push({Tag:"", Value: "", edit: true}); value = value;}}
|
||||
>
|
||||
<Icon name="plus" /> Add parameter
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
354
ui/src/lib/components/resources/CAA-issuers.ts
Normal file
354
ui/src/lib/components/resources/CAA-issuers.ts
Normal file
|
@ -0,0 +1,354 @@
|
|||
export const issuers = {
|
||||
"Actalis S.p.A.": [
|
||||
"actalis.it"
|
||||
],
|
||||
"Amazon Trust Services LLC": [
|
||||
"amazon.com",
|
||||
"amazontrust.com",
|
||||
"awstrust.com",
|
||||
"amazonaws.com",
|
||||
"aws.amazon.com"
|
||||
],
|
||||
"ANF AC": [
|
||||
"anf.es"
|
||||
],
|
||||
"Asseco Data Systems (formely Certum)": [
|
||||
"certum.pl",
|
||||
"certum.eu"
|
||||
],
|
||||
"Apple": [
|
||||
"pki.apple.com"
|
||||
],
|
||||
"Atos": [
|
||||
"atos.net"
|
||||
],
|
||||
"Beijing CA": [
|
||||
"bjca.cn"
|
||||
],
|
||||
"Buypass AS": [
|
||||
"buypass.com",
|
||||
"buypass.no"
|
||||
],
|
||||
"CAcert": [
|
||||
"cacert.org"
|
||||
],
|
||||
"AC Camerfirma S.A.": [
|
||||
"camerfirma.com"
|
||||
],
|
||||
"CATCert": [
|
||||
"aoc.cat"
|
||||
],
|
||||
"Fastly/Certainly": [
|
||||
"certainly.com"
|
||||
],
|
||||
"Certinomis": [
|
||||
"www.certinomis.com",
|
||||
"www.certinomis.fr"
|
||||
],
|
||||
"Dhimyotis": [
|
||||
"certigna.fr"
|
||||
],
|
||||
"Certizen": [
|
||||
"ecert.gov.hk",
|
||||
"hongkongpost.gov.hk"
|
||||
],
|
||||
"certSIGN": [
|
||||
"certsign.ro"
|
||||
],
|
||||
"China Financial CA (CFCA)": [
|
||||
"cfca.com.cn"
|
||||
],
|
||||
"China Internet Network Information Center (CNNIC)": [
|
||||
"cnnic.cn"
|
||||
],
|
||||
"Chunghwa Telecom": [
|
||||
"pki.hinet.net",
|
||||
"tls.hinet.net",
|
||||
"eca.hinet.net",
|
||||
"epki.com.tw",
|
||||
"publicca.hinet.net"
|
||||
],
|
||||
"ComSign Ltd": [
|
||||
"comsign.co.il",
|
||||
"comsign.co.uk",
|
||||
"comsigneurope.com"
|
||||
],
|
||||
"Cybertrust Japan": [
|
||||
"cybertrust.ne.jp",
|
||||
"jcsinc.co.jp"
|
||||
],
|
||||
"Deutsche Telekom Security": [
|
||||
"telesec.de"
|
||||
],
|
||||
"DFN-PKI": [
|
||||
"pki.dfn.de",
|
||||
"dfn.de"
|
||||
],
|
||||
"DigiCert": [
|
||||
"digicert.com",
|
||||
"symantec.com",
|
||||
"geotrust.com",
|
||||
"rapidssl.com",
|
||||
"thawte.com",
|
||||
"digitalcertvalidation.com",
|
||||
"volusion.digitalcertvalidation.com",
|
||||
"stratossl.digitalcertvalidation.com",
|
||||
"intermediatecertificate.digitalcertvalidation.com",
|
||||
"1and1.digitalcertvalidation.com"
|
||||
],
|
||||
"DigitalSign CD": [
|
||||
"digitalsign.pt"
|
||||
],
|
||||
"Disig, a.s.": [
|
||||
"disig.sk"
|
||||
],
|
||||
"DocuSign": [
|
||||
"docusign.fr"
|
||||
],
|
||||
"D-Trust GmbH": [
|
||||
"dtrust.de",
|
||||
"d-trust.de",
|
||||
"dtrust.net",
|
||||
"d-trust.net"
|
||||
],
|
||||
"DigitalTrust": [
|
||||
"digitaltrust.ae"
|
||||
],
|
||||
"EDICOM": [
|
||||
"edicomgroup.com"
|
||||
],
|
||||
"eMudhra Technologies Limited": [
|
||||
"emsign.com"
|
||||
],
|
||||
"Entrust": [
|
||||
"entrust.net",
|
||||
"affirmtrust.com"
|
||||
],
|
||||
"E-TUGRA Inc.": [
|
||||
"e-tugra.com",
|
||||
"e-tugra.com.tr",
|
||||
"etugra.com",
|
||||
"etugra.com.tr"
|
||||
],
|
||||
"AC Firmaprofesional CIF": [
|
||||
"firmaprofesional.com"
|
||||
],
|
||||
"Guang Dong CA Co.": [
|
||||
"gdca.com.cn"
|
||||
],
|
||||
"GlobalSign": [
|
||||
"globalsign.com"
|
||||
],
|
||||
"Global Trust": [
|
||||
"globaltrust.eu"
|
||||
],
|
||||
"GoDaddy Inc.": [
|
||||
"godaddy.com",
|
||||
"starfieldtech.com"
|
||||
],
|
||||
"Google Trust Services (GTS)": [
|
||||
"pki.goog",
|
||||
"google.com"
|
||||
],
|
||||
"ACCV (Spain gov)": [
|
||||
"accv.es"
|
||||
],
|
||||
"FNMT (Spain gov)": [
|
||||
"fnmt.es"
|
||||
],
|
||||
"Agence Nationale de Certification Electronique (Tunisia gov)": [
|
||||
"tuntrust.tn"
|
||||
],
|
||||
"GRCA": [
|
||||
"gca.nat.gov.tw"
|
||||
],
|
||||
"HARICA": [
|
||||
"harica.gr"
|
||||
],
|
||||
"Hongkong Post": [
|
||||
"ecert.gov.hk",
|
||||
"hongkongpost.gov.hk"
|
||||
],
|
||||
"IdenTrust": [
|
||||
"identrust.com",
|
||||
"www.identrust.com"
|
||||
],
|
||||
"iTrusChina Co.": [
|
||||
"itrus.com.cn",
|
||||
"itrus.cn"
|
||||
],
|
||||
"IZENPE S.A.": [
|
||||
"izenpe.com",
|
||||
"izenpe.eus"
|
||||
],
|
||||
"Japan Registry Services": [
|
||||
"jprs.co.jp"
|
||||
],
|
||||
"Kamu Sertifikasyon Merkezi": [
|
||||
"kamusm.gov.tr"
|
||||
],
|
||||
"KPN Corporate Market BV": [
|
||||
"kpn.com"
|
||||
],
|
||||
"Krajowa Izba Rozliczeniowa S.A. (KIR)": [
|
||||
"elektronicznypodpis.pl"
|
||||
],
|
||||
"LAWtrust": [
|
||||
"lawtrust.co.za"
|
||||
],
|
||||
"Let's Encrypt": [
|
||||
"letsencrypt.org"
|
||||
],
|
||||
"Logius PKIoverheid": [
|
||||
"logius.nl"
|
||||
],
|
||||
"Microsec Ltd.": [
|
||||
"e-szigno.hu"
|
||||
],
|
||||
"Microsoft": [
|
||||
"microsoft.com"
|
||||
],
|
||||
"Microsoft IT": [
|
||||
"ssladmin.microsoft.com"
|
||||
],
|
||||
"MSC Trustgate": [
|
||||
"msctrustgate.com"
|
||||
],
|
||||
"National Center for Digital Certification (NCDC)": [
|
||||
"ncdc.gov.sa"
|
||||
],
|
||||
"NAVER Business Platform Corp.": [
|
||||
"certificate.naver.com"
|
||||
],
|
||||
"NetLock Kft.": [
|
||||
"netlock.hu",
|
||||
"netlock.net",
|
||||
"netlock.eu"
|
||||
],
|
||||
"Networking4all": [
|
||||
"trustproviderbv.digitalcertvalidation.com"
|
||||
],
|
||||
"Network Solutions LLC": [
|
||||
"networksolutions.com",
|
||||
"web.com"
|
||||
],
|
||||
"OISTE Foundation": [
|
||||
"wisekey.com",
|
||||
"hightrusted.com",
|
||||
"certifyid.com",
|
||||
"oiste.org"
|
||||
],
|
||||
"Open Access Technology International": [
|
||||
"oati.com"
|
||||
],
|
||||
"Prvni certifikacni autorita, a.s.": [
|
||||
"ica.cz"
|
||||
],
|
||||
"PKIoverheid": [
|
||||
"www.pkioverheid.nl"
|
||||
],
|
||||
"QuoVadis": [
|
||||
"quovadisglobal.com",
|
||||
"digicert.com",
|
||||
"digicert.ne.jp",
|
||||
"cybertrust.ne.jp",
|
||||
"symantec.com",
|
||||
"thawte.com",
|
||||
"geotrust.com",
|
||||
"rapidssl.com",
|
||||
"digitalcertvalidation.com"
|
||||
],
|
||||
"SECOM Trust Systems": [
|
||||
"secomtrust.net"
|
||||
],
|
||||
"Sectigo": [
|
||||
"sectigo.com",
|
||||
"comodo.com",
|
||||
"comodoca.com",
|
||||
"usertrust.com",
|
||||
"trust-provider.com"
|
||||
],
|
||||
"Shanghai Electronic Certification Authority Co. Ltd": [
|
||||
"sheca.com",
|
||||
"imtrust.cn",
|
||||
"wwwtrust.cn"
|
||||
],
|
||||
"SK ID Solutions AS": [
|
||||
"skidsolutions.eu"
|
||||
],
|
||||
"SSL Corporation": [
|
||||
"ssl.com"
|
||||
],
|
||||
"Skaitmeninio sertifikavimo centras (SSC)": [
|
||||
"ssc.lt"
|
||||
],
|
||||
"SwissSign AG": [
|
||||
"swisssign.com",
|
||||
"swisssign.net",
|
||||
"swissign.com",
|
||||
"swisssign.ch",
|
||||
"swisssign.li",
|
||||
"swissign.li",
|
||||
"swisssign.org",
|
||||
"swisssign.biz",
|
||||
"swisstsa.ch",
|
||||
"swisstsa.li",
|
||||
"digitalid.ch",
|
||||
"digital-id.ch",
|
||||
"zert.ch",
|
||||
"rootsigning.com",
|
||||
"root-signing.ch",
|
||||
"ssl-certificate.ch",
|
||||
"managed-pki.ch",
|
||||
"managed-pki.de",
|
||||
"swissstick.com",
|
||||
"swisssigner.ch",
|
||||
"pki-posta.ch",
|
||||
"pki-poste.ch",
|
||||
"pki-post.ch",
|
||||
"trustdoc.ch",
|
||||
"trustsign.ch",
|
||||
"swisssigner.com",
|
||||
"postsuisseid.ch",
|
||||
"suisseid-service.ch",
|
||||
"signdemo.com",
|
||||
"sirb.com"
|
||||
],
|
||||
"SecureTrust Corporation": [
|
||||
"trustwave.com",
|
||||
"securetrust.com"
|
||||
],
|
||||
"TAIWAN-CA Inc. (TWCA)": [
|
||||
"twca.com.tw"
|
||||
],
|
||||
"Telia Finland Oyj": [
|
||||
"telia.com",
|
||||
"telia.fi",
|
||||
"telia.se"
|
||||
],
|
||||
"TrustCor Systems": [
|
||||
"trustcor.ca"
|
||||
],
|
||||
"T-Systems Enterprise Services": [
|
||||
"t-systems.com"
|
||||
],
|
||||
"Visa": [
|
||||
"visa.com"
|
||||
],
|
||||
"Zertificon": [
|
||||
"zertificon.com"
|
||||
],
|
||||
"360": [
|
||||
"browser.360.cn"
|
||||
]
|
||||
};
|
||||
|
||||
export const rev_issuers: Record<string, string> = { };
|
||||
|
||||
for (const issuer in issuers) {
|
||||
for (const dn of issuers[issuer]) {
|
||||
rev_issuers[dn] = issuer;
|
||||
}
|
||||
}
|
||||
|
||||
export default issuers;
|
139
ui/src/lib/components/resources/CAA.svelte
Normal file
139
ui/src/lib/components/resources/CAA.svelte
Normal file
|
@ -0,0 +1,139 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
Button,
|
||||
FormGroup,
|
||||
Icon,
|
||||
Input,
|
||||
} from 'sveltestrap';
|
||||
|
||||
import TableInput from '$lib/components/resources/table.svelte';
|
||||
import ResourceRawInput from '$lib/components/resources/raw.svelte';
|
||||
import CAAIssuer from '$lib/components/resources/CAA-issuer.svelte';
|
||||
import CAAIodef from '$lib/components/resources/CAA-iodef.svelte';
|
||||
|
||||
import issuers from './CAA-issuers';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let edit = false;
|
||||
export let index: string;
|
||||
export let readonly = false;
|
||||
export let specs: any;
|
||||
export let value: any;
|
||||
</script>
|
||||
|
||||
<h4>Certificates issuance</h4>
|
||||
|
||||
<FormGroup>
|
||||
<Input id="issuedisabled" type="checkbox" label="Disallow any certificate issuance" bind:checked={value.DisallowIssue} />
|
||||
</FormGroup>
|
||||
|
||||
<h5>
|
||||
Authorized Issuers
|
||||
</h5>
|
||||
|
||||
{#if !value.DisallowIssue}
|
||||
<ul>
|
||||
{#if value.Issue}
|
||||
{#each value.Issue as issue, k}
|
||||
<li class="mb-3">
|
||||
<CAAIssuer
|
||||
{readonly}
|
||||
bind:value={value.Issue[k]}
|
||||
on:delete-issuer={() => {value.Issue.splice(k, 1); value = value;}}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
{:else}
|
||||
<Alert color="warning" fade={false}>
|
||||
<strong>All issuer authorized.</strong> With those parameters, all issuer can create certificate for this domain and subdomain.
|
||||
</Alert>
|
||||
{/if}
|
||||
{#if !readonly}
|
||||
<li style:list-style="'+ '">
|
||||
<CAAIssuer
|
||||
newone
|
||||
on:add-issuer={(e) => {if (!value.Issue) value.Issue = []; value.Issue.push(e.detail); value = value;}}
|
||||
/>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
{:else}
|
||||
<Alert color="danger" fade={false}>
|
||||
<strong>No issuer authorized.</strong> With those parameters, no issuer is allowed to create certificate for this subdomain.
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<h4>Wildcard certificates issuance</h4>
|
||||
|
||||
<FormGroup>
|
||||
<Input id="wildcardissuedisabled" type="checkbox" label="Disallow wildcard certificate issuance" bind:checked={value.DisallowWildcardIssue} />
|
||||
</FormGroup>
|
||||
|
||||
<h5>
|
||||
Authorized Issuers
|
||||
</h5>
|
||||
|
||||
{#if !value.DisallowWildcardIssue}
|
||||
<ul>
|
||||
{#if value.IssueWild}
|
||||
{#each value.IssueWild as issue, k}
|
||||
<li class="mb-3">
|
||||
<CAAIssuer
|
||||
{readonly}
|
||||
bind:value={value.IssueWild[k]}
|
||||
on:delete-issuer={() => {value.IssueWild.splice(k, 1); value = value;}}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
{:else if value.DisallowIssue}
|
||||
<Alert color="danger" fade={false}>
|
||||
<strong>No issuer authorized.</strong> With those parameters, no issuer is authorized to create wildcard certificate for this domain and subdomain. But this can be override with the following settings:
|
||||
</Alert>
|
||||
{:else if value.Issue}
|
||||
<Alert color="warning" fade={false}>
|
||||
<strong>Same as regular certificate issuance.</strong> With those parameters, all issuer authorized for certificate issuance can also create wildcard certificate for this domain and subdomain.
|
||||
</Alert>
|
||||
{:else}
|
||||
<Alert color="warning" fade={false}>
|
||||
<strong>All issuer authorized.</strong> With those parameters, all issuer can create wildcard certificate for this domain and subdomain.
|
||||
</Alert>
|
||||
{/if}
|
||||
{#if !readonly}
|
||||
<li style:list-style="'+ '">
|
||||
<CAAIssuer
|
||||
newone
|
||||
on:add-issuer={(e) => {if (!value.IssueWild) value.IssueWild = []; value.IssueWild.push(e.detail); value = value;}}
|
||||
/>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
{:else}
|
||||
<Alert color="danger" fade={false}>
|
||||
<strong>No wildcard issuer authorized.</strong> With those parameters, no issuer is allowed to create wildcard certificate for this subdomain.
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<h4>Incident Response</h4>
|
||||
|
||||
<p>
|
||||
How would you want to be contacted in case of violation of the current security policy?
|
||||
</p>
|
||||
|
||||
{#if value.Iodef}
|
||||
{#each value.Iodef as iodef, k}
|
||||
<CAAIodef
|
||||
{readonly}
|
||||
bind:value={value.Iodef[k]}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if !readonly}
|
||||
<CAAIodef
|
||||
newone
|
||||
/>
|
||||
{/if}
|
|
@ -8,6 +8,6 @@ export function fillUndefinedValues(value: any, spec: Field) {
|
|||
if (spec.default !== undefined) value[spec.id] = spec.default;
|
||||
else if (vartype == "[]uint8") value[spec.id] = "";
|
||||
else if (vartype.startsWith("[]")) value[spec.id] = [];
|
||||
else if (vartype != "string" && !vartype.startsWith("uint") && !vartype.startsWith("int") && vartype != "net.IP" && vartype != "time.Duration" && vartype != "common.Duration") value[spec.id] = { };
|
||||
else if (vartype != "string" && !vartype.startsWith("uint") && !vartype.startsWith("int") && vartype != "net.IP" && vartype != "common.URL" && vartype != "time.Duration" && vartype != "common.Duration") value[spec.id] = { };
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user