Introduce CAA record
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
cd29ec9eb0
commit
99689080de
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
|
@ -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> {
|
export async function getServiceSpec(ssid: string): Promise<ServiceSpec> {
|
||||||
if (ssid == "string") {
|
if (ssid == "string" || ssid == "common.URL") {
|
||||||
return Promise.resolve(<ServiceSpec>{fields: null});
|
return Promise.resolve(<ServiceSpec>{fields: null});
|
||||||
} else {
|
} else {
|
||||||
const res = await fetch(`/api/service_specs/` + ssid, {
|
const res = await fetch(`/api/service_specs/` + ssid, {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
import BasicInput from '$lib/components/resources/basic.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 MapInput from '$lib/components/resources/map.svelte';
|
||||||
import ObjectInput from '$lib/components/resources/object.svelte';
|
import ObjectInput from '$lib/components/resources/object.svelte';
|
||||||
import RawInput from '$lib/components/resources/raw.svelte';
|
import RawInput from '$lib/components/resources/raw.svelte';
|
||||||
|
@ -45,6 +46,16 @@
|
||||||
type={sanitizeType(type)}
|
type={sanitizeType(type)}
|
||||||
bind:value={value}
|
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)}
|
{:else if typeof value === 'object' || Array.isArray(specs)}
|
||||||
<ObjectInput
|
<ObjectInput
|
||||||
{edit}
|
{edit}
|
||||||
|
|
|
@ -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>
|
|
@ -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}
|
|
@ -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;
|
|
@ -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;
|
if (spec.default !== undefined) value[spec.id] = spec.default;
|
||||||
else if (vartype == "[]uint8") value[spec.id] = "";
|
else if (vartype == "[]uint8") value[spec.id] = "";
|
||||||
else if (vartype.startsWith("[]")) 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