Merge pull request #34488 from mikedanese/signing-profile

Automatic merge from submit-queue

certificates: add a signing profile to the internal types

Here is a strawman of a CertificateSigningProfile type which would be used by the certificates controller when configuring cfssl. Side question: what magnitude of change warrants a design proposal?

@liggitt @gtank
This commit is contained in:
Kubernetes Submit Queue 2017-01-10 15:33:59 -08:00 committed by GitHub
commit 41689b15bd
20 changed files with 1325 additions and 685 deletions

View File

@ -35833,6 +35833,13 @@
"uid": {
"type": "string"
},
"usages": {
"description": "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12",
"type": "array",
"items": {
"type": "string"
}
},
"username": {
"description": "Information about the requesting user (if relevant) See user.Info interface for details",
"type": "string"

View File

@ -895,6 +895,13 @@
"type": "string",
"description": "Base64-encoded PKCS#10 CSR data"
},
"usages": {
"type": "array",
"items": {
"$ref": "v1alpha1.KeyUsage"
},
"description": "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12"
},
"username": {
"type": "string",
"description": "Information about the requesting user (if relevant) See user.Info interface for details"
@ -910,6 +917,10 @@
}
}
},
"v1alpha1.KeyUsage": {
"id": "v1alpha1.KeyUsage",
"properties": {}
},
"v1alpha1.CertificateSigningRequestStatus": {
"id": "v1alpha1.CertificateSigningRequestStatus",
"properties": {

View File

@ -588,6 +588,14 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">usages</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">allowedUsages specifies a set of usage contexts the key will be valid for. See: <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.3">https://tools.ietf.org/html/rfc5280#section-4.2.1.3</a><br>
<a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.12">https://tools.ietf.org/html/rfc5280#section-4.2.1.12</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1alpha1_keyusage">v1alpha1.KeyUsage</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">username</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Information about the requesting user (if relevant) See user.Info interface for details</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -983,6 +991,10 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1alpha1_keyusage">v1alpha1.KeyUsage</h3>
</div>
<div class="sect2">
<h3 id="_v1_watchevent">v1.WatchEvent</h3>
@ -1352,7 +1364,7 @@ Examples:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-01-06 18:14:37 UTC
Last updated 2017-01-09 21:23:51 UTC
</div>
</div>
</body>

View File

@ -46,6 +46,12 @@ type CertificateSigningRequestSpec struct {
// Base64-encoded PKCS#10 CSR data
Request []byte
// usages specifies a set of usage contexts the key will be
// valid for.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12
Usages []KeyUsage
// Information about the requesting user (if relevant)
// See user.Info interface for details
// +optional
@ -96,3 +102,34 @@ type CertificateSigningRequestList struct {
// +optional
Items []CertificateSigningRequest
}
// KeyUsages specifies valid usage contexts for keys.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12
type KeyUsage string
const (
UsageSigning KeyUsage = "signing"
UsageDigitalSignature KeyUsage = "digital signature"
UsageContentCommittment KeyUsage = "content committment"
UsageKeyEncipherment KeyUsage = "key encipherment"
UsageKeyAgreement KeyUsage = "key agreement"
UsageDataEncipherment KeyUsage = "data encipherment"
UsageCertSign KeyUsage = "cert sign"
UsageCRLSign KeyUsage = "crl sign"
UsageEncipherOnly KeyUsage = "encipher only"
UsageDecipherOnly KeyUsage = "decipher only"
UsageAny KeyUsage = "any"
UsageServerAuth KeyUsage = "server auth"
UsageClientAuth KeyUsage = "client auth"
UsageCodeSigning KeyUsage = "code signing"
UsageEmailProtection KeyUsage = "email protection"
UsageSMIME KeyUsage = "s/mime"
UsageIPsecEndSystem KeyUsage = "ipsec end system"
UsageIPsecTunnel KeyUsage = "ipsec tunnel"
UsageIPsecUser KeyUsage = "ipsec user"
UsageTimestamping KeyUsage = "timestamping"
UsageOCSPSigning KeyUsage = "ocsp signing"
UsageMicrosoftSGC KeyUsage = "microsoft sgc"
UsageNetscapSGC KeyUsage = "netscape sgc"
)

View File

@ -250,6 +250,21 @@ func (m *CertificateSigningRequestSpec) MarshalTo(data []byte) (int, error) {
i += copy(data[i:], s)
}
}
if len(m.Usages) > 0 {
for _, s := range m.Usages {
data[i] = 0x2a
i++
l = len(s)
for l >= 1<<7 {
data[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
data[i] = uint8(l)
i++
i += copy(data[i:], s)
}
}
return i, nil
}
@ -373,6 +388,12 @@ func (m *CertificateSigningRequestSpec) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
}
}
if len(m.Usages) > 0 {
for _, s := range m.Usages {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
@ -450,6 +471,7 @@ func (this *CertificateSigningRequestSpec) String() string {
`Username:` + fmt.Sprintf("%v", this.Username) + `,`,
`UID:` + fmt.Sprintf("%v", this.UID) + `,`,
`Groups:` + fmt.Sprintf("%v", this.Groups) + `,`,
`Usages:` + fmt.Sprintf("%v", this.Usages) + `,`,
`}`,
}, "")
return s
@ -1038,6 +1060,35 @@ func (m *CertificateSigningRequestSpec) Unmarshal(data []byte) error {
}
m.Groups = append(m.Groups, string(data[iNdEx:postIndex]))
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Usages", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Usages = append(m.Usages, KeyUsage(data[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(data[iNdEx:])
@ -1277,49 +1328,50 @@ var (
)
var fileDescriptorGenerated = []byte{
// 691 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x4f, 0x13, 0x4f,
0x18, 0xee, 0xb6, 0xa5, 0xb4, 0x53, 0x7e, 0xf0, 0xcb, 0xc4, 0x98, 0x4a, 0xc2, 0x96, 0x34, 0x6a,
0xaa, 0x81, 0x59, 0x4b, 0x3c, 0x70, 0x34, 0x8b, 0x89, 0x21, 0x42, 0x88, 0x03, 0x24, 0x86, 0xdb,
0x74, 0xfb, 0xb2, 0x1d, 0xcb, 0xfe, 0x61, 0x67, 0x96, 0x84, 0x9b, 0x47, 0x8f, 0xde, 0xfd, 0x20,
0x7e, 0x05, 0x8e, 0x1c, 0x3d, 0x55, 0x29, 0x67, 0xbf, 0x80, 0x27, 0x33, 0xd3, 0xe9, 0x1f, 0x5b,
0x0a, 0x9a, 0x70, 0xeb, 0xfb, 0xcc, 0xfb, 0x3e, 0xcf, 0xfb, 0xe7, 0xe9, 0xa2, 0x57, 0x9d, 0x4d,
0x41, 0x78, 0xe4, 0x74, 0xd2, 0x26, 0x24, 0x21, 0x48, 0x10, 0x4e, 0xdc, 0xf1, 0x1d, 0x16, 0x73,
0xe1, 0x78, 0x90, 0x48, 0x7e, 0xcc, 0x3d, 0xa6, 0xd0, 0xb3, 0x06, 0x3b, 0x89, 0xdb, 0xac, 0xe1,
0xf8, 0x10, 0x42, 0xc2, 0x24, 0xb4, 0x48, 0x9c, 0x44, 0x32, 0xc2, 0x2f, 0xfa, 0x0c, 0x64, 0xc4,
0x40, 0xe2, 0x8e, 0x4f, 0x14, 0x03, 0x19, 0x67, 0x20, 0x03, 0x86, 0xe5, 0x75, 0x9f, 0xcb, 0x76,
0xda, 0x24, 0x5e, 0x14, 0x38, 0x7e, 0xe4, 0x47, 0x8e, 0x26, 0x6a, 0xa6, 0xc7, 0x3a, 0xd2, 0x81,
0xfe, 0xd5, 0x17, 0x58, 0xde, 0x98, 0xd9, 0xa2, 0x93, 0x80, 0x88, 0xd2, 0xc4, 0x83, 0xc9, 0xa6,
0x96, 0xd7, 0x66, 0xd7, 0x9c, 0x4d, 0x8d, 0x70, 0x8b, 0x82, 0x70, 0x02, 0x90, 0xec, 0xa6, 0x9a,
0xf5, 0x9b, 0x6b, 0x92, 0x34, 0x94, 0x3c, 0x98, 0x6e, 0xe8, 0xe5, 0xed, 0xe9, 0xc2, 0x6b, 0x43,
0xc0, 0xa6, 0xaa, 0x1a, 0x37, 0x57, 0xa5, 0x92, 0x9f, 0x38, 0x3c, 0x94, 0x42, 0x26, 0x93, 0x25,
0xb5, 0xeb, 0x2c, 0x7a, 0xb4, 0x35, 0x5a, 0xfb, 0x3e, 0xf7, 0x43, 0x1e, 0xfa, 0x14, 0x4e, 0x53,
0x10, 0x12, 0xbf, 0x47, 0x45, 0x35, 0x50, 0x8b, 0x49, 0x56, 0xb1, 0x56, 0xad, 0x7a, 0x79, 0xa3,
0x4e, 0x66, 0xde, 0x8f, 0x9c, 0x35, 0xc8, 0x5e, 0xf3, 0x03, 0x78, 0x72, 0x17, 0x24, 0x73, 0xf1,
0x45, 0xb7, 0x9a, 0xe9, 0x75, 0xab, 0x68, 0x84, 0xd1, 0x21, 0x1b, 0x3e, 0x45, 0x79, 0x11, 0x83,
0x57, 0xc9, 0x6a, 0xd6, 0x3d, 0xf2, 0xaf, 0xae, 0x20, 0x33, 0x9b, 0xde, 0x8f, 0xc1, 0x73, 0x17,
0x8c, 0x78, 0x5e, 0x45, 0x54, 0x4b, 0xe1, 0x73, 0x54, 0x10, 0x92, 0xc9, 0x54, 0x54, 0x72, 0x5a,
0xf4, 0xdd, 0x7d, 0x8a, 0x6a, 0x62, 0x77, 0xd1, 0xc8, 0x16, 0xfa, 0x31, 0x35, 0x82, 0xb5, 0x2f,
0x59, 0x54, 0x9b, 0x59, 0xbb, 0x15, 0x85, 0x2d, 0x2e, 0x79, 0x14, 0xe2, 0x4d, 0x94, 0x97, 0xe7,
0x31, 0xe8, 0x55, 0x97, 0xdc, 0xc7, 0x83, 0x19, 0x0e, 0xce, 0x63, 0xf8, 0xd5, 0xad, 0x3e, 0x98,
0xcc, 0x57, 0x38, 0xd5, 0x15, 0xf8, 0x29, 0x2a, 0x24, 0xc0, 0x44, 0x14, 0xea, 0x85, 0x96, 0x46,
0x8d, 0x50, 0x8d, 0x52, 0xf3, 0x8a, 0x9f, 0xa1, 0xf9, 0x00, 0x84, 0x60, 0x3e, 0xe8, 0x25, 0x94,
0xdc, 0x25, 0x93, 0x38, 0xbf, 0xdb, 0x87, 0xe9, 0xe0, 0x1d, 0xb7, 0xd1, 0xe2, 0x09, 0x13, 0xf2,
0x30, 0x6e, 0x31, 0x09, 0x07, 0x3c, 0x80, 0x4a, 0xfe, 0x2e, 0x07, 0x08, 0xa2, 0xee, 0xab, 0x7c,
0xa0, 0xf2, 0xdd, 0x87, 0x86, 0x7b, 0x71, 0xe7, 0x0f, 0x1e, 0x3a, 0xc1, 0x5b, 0xfb, 0x69, 0xa1,
0x95, 0x99, 0xdb, 0xd9, 0xe1, 0x42, 0xe2, 0xa3, 0x29, 0x1f, 0xae, 0xfd, 0x4d, 0x17, 0xaa, 0x56,
0x7b, 0xf1, 0x7f, 0xd3, 0x49, 0x71, 0x80, 0x8c, 0x39, 0x31, 0x46, 0x73, 0x5c, 0x42, 0x20, 0x2a,
0xd9, 0xd5, 0x5c, 0xbd, 0xbc, 0xf1, 0xf6, 0x1e, 0x5d, 0xe1, 0xfe, 0x67, 0x74, 0xe7, 0xb6, 0x95,
0x02, 0xed, 0x0b, 0xd5, 0xbe, 0xde, 0x36, 0xaf, 0x32, 0x2c, 0x7e, 0x82, 0xe6, 0x93, 0x7e, 0xa8,
0xc7, 0x5d, 0x70, 0xcb, 0xea, 0x44, 0x26, 0x83, 0x0e, 0xde, 0xf0, 0x1a, 0x2a, 0xa6, 0x02, 0x92,
0x90, 0x05, 0x60, 0xee, 0x3e, 0x1c, 0xf4, 0xd0, 0xe0, 0x74, 0x98, 0x81, 0x57, 0x50, 0x2e, 0xe5,
0x2d, 0x73, 0xf7, 0xb2, 0x49, 0xcc, 0x1d, 0x6e, 0xbf, 0xa6, 0x0a, 0xc7, 0x35, 0x54, 0xf0, 0x93,
0x28, 0x8d, 0x45, 0x25, 0xbf, 0x9a, 0xab, 0x97, 0x5c, 0xa4, 0xec, 0xf3, 0x46, 0x23, 0xd4, 0xbc,
0xd4, 0xbe, 0x5b, 0xa8, 0x7a, 0xc7, 0x7f, 0x00, 0x7f, 0xb2, 0x10, 0xf2, 0x06, 0x16, 0x15, 0x15,
0x4b, 0x6f, 0xf5, 0xe0, 0x1e, 0xb7, 0x3a, 0xf4, 0xff, 0xe8, 0x13, 0x33, 0x84, 0x04, 0x1d, 0xd3,
0xc6, 0x0d, 0x54, 0x1e, 0xe3, 0xd6, 0x2b, 0x5a, 0x70, 0x97, 0x7a, 0xdd, 0x6a, 0x79, 0x8c, 0x9c,
0x8e, 0xe7, 0xb8, 0xcf, 0x2f, 0xae, 0xec, 0xcc, 0xe5, 0x95, 0x9d, 0xf9, 0x76, 0x65, 0x67, 0x3e,
0xf6, 0x6c, 0xeb, 0xa2, 0x67, 0x5b, 0x97, 0x3d, 0xdb, 0xfa, 0xd1, 0xb3, 0xad, 0xcf, 0xd7, 0x76,
0xe6, 0xa8, 0x38, 0xe8, 0xf0, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x02, 0x0e, 0x3c, 0x0d,
0x07, 0x00, 0x00,
// 716 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x54, 0x3d, 0x4f, 0x1b, 0x4b,
0x14, 0xf5, 0xda, 0xc6, 0xd8, 0x63, 0x1e, 0x3c, 0x8d, 0x9e, 0x90, 0x1f, 0x12, 0x6b, 0x64, 0x25,
0x91, 0x13, 0xc1, 0x6e, 0x6c, 0xa5, 0xa0, 0x8c, 0x96, 0x48, 0x11, 0x02, 0x84, 0x32, 0x60, 0x29,
0xa2, 0x1b, 0xaf, 0x2f, 0xeb, 0x89, 0xd9, 0x0f, 0x76, 0x66, 0x91, 0xdc, 0xa5, 0x4c, 0x99, 0x3e,
0x7f, 0x88, 0x92, 0x32, 0x95, 0x13, 0x4c, 0x19, 0xe5, 0x0f, 0x50, 0x45, 0x33, 0x1e, 0x7f, 0xc4,
0xc6, 0x90, 0x48, 0x74, 0x9e, 0x33, 0xe7, 0x9e, 0x73, 0xe7, 0xde, 0xb3, 0x46, 0xaf, 0x3b, 0xdb,
0xdc, 0x62, 0xa1, 0xdd, 0x49, 0x9a, 0x10, 0x07, 0x20, 0x80, 0xdb, 0x51, 0xc7, 0xb3, 0x69, 0xc4,
0xb8, 0xed, 0x42, 0x2c, 0xd8, 0x29, 0x73, 0xa9, 0x44, 0x2f, 0x6a, 0xf4, 0x2c, 0x6a, 0xd3, 0x9a,
0xed, 0x41, 0x00, 0x31, 0x15, 0xd0, 0xb2, 0xa2, 0x38, 0x14, 0x21, 0x7e, 0x39, 0x50, 0xb0, 0xc6,
0x0a, 0x56, 0xd4, 0xf1, 0x2c, 0xa9, 0x60, 0x4d, 0x2a, 0x58, 0x43, 0x85, 0xb5, 0x2d, 0x8f, 0x89,
0x76, 0xd2, 0xb4, 0xdc, 0xd0, 0xb7, 0xbd, 0xd0, 0x0b, 0x6d, 0x25, 0xd4, 0x4c, 0x4e, 0xd5, 0x49,
0x1d, 0xd4, 0xaf, 0x81, 0xc1, 0x5a, 0x7d, 0x6e, 0x8b, 0x76, 0x0c, 0x3c, 0x4c, 0x62, 0x17, 0xa6,
0x9b, 0x5a, 0xdb, 0x9c, 0x5f, 0x73, 0x31, 0xf3, 0x84, 0x7b, 0x1c, 0xb8, 0xed, 0x83, 0xa0, 0x77,
0xd5, 0x6c, 0xdd, 0x5d, 0x13, 0x27, 0x81, 0x60, 0xfe, 0x6c, 0x43, 0xaf, 0xee, 0xa7, 0x73, 0xb7,
0x0d, 0x3e, 0x9d, 0xa9, 0xaa, 0xdd, 0x5d, 0x95, 0x08, 0x76, 0x66, 0xb3, 0x40, 0x70, 0x11, 0x4f,
0x97, 0x54, 0x6e, 0xd2, 0xe8, 0xff, 0x9d, 0xf1, 0xd8, 0x8f, 0x98, 0x17, 0xb0, 0xc0, 0x23, 0x70,
0x9e, 0x00, 0x17, 0xf8, 0x3d, 0xca, 0xcb, 0x07, 0xb5, 0xa8, 0xa0, 0x25, 0x63, 0xc3, 0xa8, 0x16,
0xeb, 0x55, 0x6b, 0xee, 0xfe, 0xac, 0x8b, 0x9a, 0x75, 0xd8, 0xfc, 0x00, 0xae, 0x38, 0x00, 0x41,
0x1d, 0x7c, 0xd9, 0x2b, 0xa7, 0xfa, 0xbd, 0x32, 0x1a, 0x63, 0x64, 0xa4, 0x86, 0xcf, 0x51, 0x96,
0x47, 0xe0, 0x96, 0xd2, 0x4a, 0xf5, 0xd0, 0xfa, 0xdb, 0x54, 0x58, 0x73, 0x9b, 0x3e, 0x8a, 0xc0,
0x75, 0x96, 0xb4, 0x79, 0x56, 0x9e, 0x88, 0xb2, 0xc2, 0x5d, 0x94, 0xe3, 0x82, 0x8a, 0x84, 0x97,
0x32, 0xca, 0xf4, 0xdd, 0x63, 0x9a, 0x2a, 0x61, 0x67, 0x59, 0xdb, 0xe6, 0x06, 0x67, 0xa2, 0x0d,
0x2b, 0x5f, 0xd2, 0xa8, 0x32, 0xb7, 0x76, 0x27, 0x0c, 0x5a, 0x4c, 0xb0, 0x30, 0xc0, 0xdb, 0x28,
0x2b, 0xba, 0x11, 0xa8, 0x51, 0x17, 0x9c, 0x27, 0xc3, 0x37, 0x1c, 0x77, 0x23, 0xb8, 0xed, 0x95,
0xff, 0x9b, 0xe6, 0x4b, 0x9c, 0xa8, 0x0a, 0xfc, 0x0c, 0xe5, 0x62, 0xa0, 0x3c, 0x0c, 0xd4, 0x40,
0x0b, 0xe3, 0x46, 0x88, 0x42, 0x89, 0xbe, 0xc5, 0xcf, 0xd1, 0xa2, 0x0f, 0x9c, 0x53, 0x0f, 0xd4,
0x10, 0x0a, 0xce, 0x8a, 0x26, 0x2e, 0x1e, 0x0c, 0x60, 0x32, 0xbc, 0xc7, 0x6d, 0xb4, 0x7c, 0x46,
0xb9, 0x68, 0x44, 0x2d, 0x2a, 0xe0, 0x98, 0xf9, 0x50, 0xca, 0x3e, 0x94, 0x00, 0x6e, 0xc9, 0xfd,
0xca, 0x1c, 0x48, 0xbe, 0xb3, 0xaa, 0xb5, 0x97, 0xf7, 0x7f, 0xd3, 0x21, 0x53, 0xba, 0x95, 0x9f,
0x06, 0x5a, 0x9f, 0x3b, 0x9d, 0x7d, 0xc6, 0x05, 0x3e, 0x99, 0xc9, 0xe1, 0xe6, 0x9f, 0x74, 0x21,
0x6b, 0x55, 0x16, 0xff, 0xd5, 0x9d, 0xe4, 0x87, 0xc8, 0x44, 0x12, 0x23, 0xb4, 0xc0, 0x04, 0xf8,
0xbc, 0x94, 0xde, 0xc8, 0x54, 0x8b, 0xf5, 0xbd, 0x47, 0x4c, 0x85, 0xf3, 0x8f, 0xf6, 0x5d, 0xd8,
0x95, 0x0e, 0x64, 0x60, 0x54, 0xf9, 0x71, 0xdf, 0x7b, 0x65, 0x60, 0xf1, 0x53, 0xb4, 0x18, 0x0f,
0x8e, 0xea, 0xb9, 0x4b, 0x4e, 0x51, 0xae, 0x48, 0x33, 0xc8, 0xf0, 0x0e, 0x6f, 0xa2, 0x7c, 0xc2,
0x21, 0x0e, 0xa8, 0x0f, 0x7a, 0xef, 0xa3, 0x87, 0x36, 0x34, 0x4e, 0x46, 0x0c, 0xbc, 0x8e, 0x32,
0x09, 0x6b, 0xe9, 0xbd, 0x17, 0x35, 0x31, 0xd3, 0xd8, 0x7d, 0x43, 0x24, 0x8e, 0x2b, 0x28, 0xe7,
0xc5, 0x61, 0x12, 0xf1, 0x52, 0x76, 0x23, 0x53, 0x2d, 0x38, 0x48, 0xc6, 0xe7, 0xad, 0x42, 0x88,
0xbe, 0xc1, 0x75, 0x94, 0xef, 0x40, 0xb7, 0xa1, 0xf2, 0xb3, 0xa0, 0x58, 0xab, 0x92, 0xa5, 0x00,
0x7e, 0xdb, 0x2b, 0xe7, 0xf7, 0xf4, 0x2d, 0x19, 0xf1, 0x2a, 0xdf, 0x0c, 0x54, 0x7e, 0xe0, 0xbb,
0xc1, 0x9f, 0x0c, 0x84, 0xdc, 0x61, 0xac, 0x79, 0xc9, 0x50, 0x9b, 0x38, 0x7e, 0xc4, 0x4d, 0x8c,
0xbe, 0x99, 0xf1, 0xdf, 0xd2, 0x08, 0xe2, 0x64, 0xc2, 0x1b, 0xd7, 0x50, 0x71, 0x42, 0x5b, 0x8d,
0x75, 0xc9, 0x59, 0xe9, 0xf7, 0xca, 0xc5, 0x09, 0x71, 0x32, 0xc9, 0x71, 0x5e, 0x5c, 0x5e, 0x9b,
0xa9, 0xab, 0x6b, 0x33, 0xf5, 0xf5, 0xda, 0x4c, 0x7d, 0xec, 0x9b, 0xc6, 0x65, 0xdf, 0x34, 0xae,
0xfa, 0xa6, 0xf1, 0xbd, 0x6f, 0x1a, 0x9f, 0x6f, 0xcc, 0xd4, 0x49, 0x7e, 0xd8, 0xe1, 0xaf, 0x00,
0x00, 0x00, 0xff, 0xff, 0x32, 0x58, 0xf7, 0xcf, 0x41, 0x07, 0x00, 0x00,
}

View File

@ -76,6 +76,12 @@ message CertificateSigningRequestSpec {
// Base64-encoded PKCS#10 CSR data
optional bytes request = 1;
// allowedUsages specifies a set of usage contexts the key will be
// valid for.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12
repeated string keyUsage = 5;
// Information about the requesting user (if relevant)
// See user.Info interface for details
// +optional

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,12 @@ type CertificateSigningRequestSpec struct {
// Base64-encoded PKCS#10 CSR data
Request []byte `json:"request" protobuf:"bytes,1,opt,name=request"`
// allowedUsages specifies a set of usage contexts the key will be
// valid for.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12
Usages []KeyUsage `json:"usages,omitempty" protobuf:"bytes,5,opt,name=keyUsage"`
// Information about the requesting user (if relevant)
// See user.Info interface for details
// +optional
@ -95,3 +101,34 @@ type CertificateSigningRequestList struct {
Items []CertificateSigningRequest `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// KeyUsages specifies valid usage contexts for keys.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12
type KeyUsage string
const (
UsageSigning KeyUsage = "signing"
UsageDigitalSignature KeyUsage = "digital signature"
UsageContentCommittment KeyUsage = "content committment"
UsageKeyEncipherment KeyUsage = "key encipherment"
UsageKeyAgreement KeyUsage = "key agreement"
UsageDataEncipherment KeyUsage = "data encipherment"
UsageCertSign KeyUsage = "cert sign"
UsageCRLSign KeyUsage = "crl sign"
UsageEncipherOnly KeyUsage = "encipher only"
UsageDecipherOnly KeyUsage = "decipher only"
UsageAny KeyUsage = "any"
UsageServerAuth KeyUsage = "server auth"
UsageClientAuth KeyUsage = "client auth"
UsageCodeSigning KeyUsage = "code signing"
UsageEmailProtection KeyUsage = "email protection"
UsageSMIME KeyUsage = "s/mime"
UsageIPsecEndSystem KeyUsage = "ipsec end system"
UsageIPsecTunnel KeyUsage = "ipsec tunnel"
UsageIPsecUser KeyUsage = "ipsec user"
UsageTimestamping KeyUsage = "timestamping"
UsageOCSPSigning KeyUsage = "ocsp signing"
UsageMicrosoftSGC KeyUsage = "microsoft sgc"
UsageNetscapSGC KeyUsage = "netscape sgc"
)

View File

@ -51,6 +51,7 @@ func (CertificateSigningRequestCondition) SwaggerDoc() map[string]string {
var map_CertificateSigningRequestSpec = map[string]string{
"": "This information is immutable after the request is created. Only the Request and ExtraInfo fields can be set on creation, other fields are derived by Kubernetes and cannot be modified by users.",
"request": "Base64-encoded PKCS#10 CSR data",
"usages": "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12",
"username": "Information about the requesting user (if relevant) See user.Info interface for details",
}

View File

@ -130,6 +130,7 @@ func Convert_certificates_CertificateSigningRequestList_To_v1alpha1_CertificateS
func autoConvert_v1alpha1_CertificateSigningRequestSpec_To_certificates_CertificateSigningRequestSpec(in *CertificateSigningRequestSpec, out *certificates.CertificateSigningRequestSpec, s conversion.Scope) error {
out.Request = *(*[]byte)(unsafe.Pointer(&in.Request))
out.Usages = *(*[]certificates.KeyUsage)(unsafe.Pointer(&in.Usages))
out.Username = in.Username
out.UID = in.UID
out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups))
@ -142,6 +143,7 @@ func Convert_v1alpha1_CertificateSigningRequestSpec_To_certificates_CertificateS
func autoConvert_certificates_CertificateSigningRequestSpec_To_v1alpha1_CertificateSigningRequestSpec(in *certificates.CertificateSigningRequestSpec, out *CertificateSigningRequestSpec, s conversion.Scope) error {
out.Request = *(*[]byte)(unsafe.Pointer(&in.Request))
out.Usages = *(*[]KeyUsage)(unsafe.Pointer(&in.Usages))
out.Username = in.Username
out.UID = in.UID
out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups))

View File

@ -99,6 +99,13 @@ func DeepCopy_v1alpha1_CertificateSigningRequestSpec(in interface{}, out interfa
*out = make([]byte, len(*in))
copy(*out, *in)
}
if in.Usages != nil {
in, out := &in.Usages, &out.Usages
*out = make([]KeyUsage, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
}
if in.Groups != nil {
in, out := &in.Groups, &out.Groups
*out = make([]string, len(*in))

View File

@ -99,6 +99,13 @@ func DeepCopy_certificates_CertificateSigningRequestSpec(in interface{}, out int
*out = make([]byte, len(*in))
copy(*out, *in)
}
if in.Usages != nil {
in, out := &in.Usages, &out.Usages
*out = make([]KeyUsage, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
}
if in.Groups != nil {
in, out := &in.Groups, &out.Groups
*out = make([]string, len(*in))

View File

@ -5,6 +5,7 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
@ -12,6 +13,7 @@ go_library(
srcs = [
"certificate_controller.go",
"certificate_controller_utils.go",
"cfssl_signer.go",
"doc.go",
"groupapprove.go",
],
@ -32,6 +34,7 @@ go_library(
"//pkg/util/workqueue:go_default_library",
"//pkg/watch:go_default_library",
"//vendor:github.com/cloudflare/cfssl/config",
"//vendor:github.com/cloudflare/cfssl/helpers",
"//vendor:github.com/cloudflare/cfssl/signer",
"//vendor:github.com/cloudflare/cfssl/signer/local",
"//vendor:github.com/golang/glog",
@ -50,3 +53,19 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["cfssl_signer_test.go"],
data = [
"testdata/ca.crt",
"testdata/ca.key",
"testdata/kubelet.csr",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/apis/certificates/v1alpha1:go_default_library",
"//pkg/util/cert:go_default_library",
],
)

View File

@ -33,9 +33,6 @@ import (
"k8s.io/kubernetes/pkg/util/workqueue"
"k8s.io/kubernetes/pkg/watch"
"github.com/cloudflare/cfssl/config"
"github.com/cloudflare/cfssl/signer"
"github.com/cloudflare/cfssl/signer/local"
"github.com/golang/glog"
)
@ -43,6 +40,10 @@ type AutoApprover interface {
AutoApprove(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, error)
}
type Signer interface {
Sign(csr *certificates.CertificateSigningRequest) ([]byte, error)
}
type CertificateController struct {
kubeClient clientset.Interface
@ -53,8 +54,7 @@ type CertificateController struct {
syncHandler func(csrKey string) error
approver AutoApprover
signer *local.Signer
signer Signer
queue workqueue.RateLimitingInterface
}
@ -65,12 +65,7 @@ func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Du
eventBroadcaster.StartLogging(glog.Infof)
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")})
// Configure cfssl signer
// TODO: support non-default policy and remote/pkcs11 signing
policy := &config.Signing{
Default: config.DefaultConfig(),
}
ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy)
s, err := NewCFSSLSigner(caCertFile, caKeyFile)
if err != nil {
return nil, err
}
@ -78,7 +73,7 @@ func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Du
cc := &CertificateController{
kubeClient: kubeClient,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "certificate"),
signer: ca,
signer: s,
approver: approver,
}
@ -209,9 +204,7 @@ func (cc *CertificateController) maybeSignCertificate(key string) error {
// 3. Update the Status subresource
if csr.Status.Certificate == nil && IsCertificateRequestApproved(csr) {
pemBytes := csr.Spec.Request
req := signer.SignRequest{Request: string(pemBytes)}
certBytes, err := cc.signer.Sign(req)
certBytes, err := cc.signer.Sign(csr)
if err != nil {
return err
}

View File

@ -0,0 +1,99 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 certificates
import (
"crypto"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
certificates "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1"
"github.com/cloudflare/cfssl/config"
"github.com/cloudflare/cfssl/helpers"
"github.com/cloudflare/cfssl/signer"
"github.com/cloudflare/cfssl/signer/local"
)
var onlySigningPolicy = &config.Signing{
Default: &config.SigningProfile{
Usage: []string{"signing"},
Expiry: helpers.OneYear,
ExpiryString: "8760h",
},
}
type CFSSLSigner struct {
ca *x509.Certificate
priv crypto.Signer
sigAlgo x509.SignatureAlgorithm
}
func NewCFSSLSigner(caFile, caKeyFile string) (*CFSSLSigner, error) {
ca, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, err
}
cakey, err := ioutil.ReadFile(caKeyFile)
if err != nil {
return nil, err
}
parsedCa, err := helpers.ParseCertificatePEM(ca)
if err != nil {
return nil, err
}
strPassword := os.Getenv("CFSSL_CA_PK_PASSWORD")
password := []byte(strPassword)
if strPassword == "" {
password = nil
}
priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password)
if err != nil {
return nil, fmt.Errorf("Malformed private key %v", err)
}
return &CFSSLSigner{
priv: priv,
ca: parsedCa,
sigAlgo: signer.DefaultSigAlgo(priv),
}, nil
}
func (cs *CFSSLSigner) Sign(csr *certificates.CertificateSigningRequest) ([]byte, error) {
var usages []string
for _, usage := range csr.Spec.Usages {
usages = append(usages, string(usage))
}
policy := &config.Signing{
Default: &config.SigningProfile{
Usage: usages,
Expiry: helpers.OneYear,
ExpiryString: "8760h",
},
}
s, err := local.NewSigner(cs.priv, cs.ca, cs.sigAlgo, policy)
if err != nil {
return nil, err
}
return s.Sign(signer.SignRequest{
Request: string(csr.Spec.Request),
})
}

View File

@ -0,0 +1,82 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 certificates
import (
"crypto/x509"
"io/ioutil"
"reflect"
"testing"
capi "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1"
"k8s.io/kubernetes/pkg/util/cert"
)
func TestSigner(t *testing.T) {
s, err := NewCFSSLSigner("./testdata/ca.crt", "./testdata/ca.key")
if err != nil {
t.Fatalf("failed to create signer: %v", err)
}
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
if err != nil {
t.Fatalf("failed to read CSR: %v", err)
}
csr := &capi.CertificateSigningRequest{
Spec: capi.CertificateSigningRequestSpec{
Request: []byte(csrb),
Usages: []capi.KeyUsage{
capi.UsageSigning,
capi.UsageKeyEncipherment,
capi.UsageServerAuth,
capi.UsageClientAuth,
},
},
}
certData, err := s.Sign(csr)
if err != nil {
t.Fatalf("failed to sign CSR: %v", err)
}
if len(certData) == 0 {
t.Fatalf("expected a certificate after signing")
}
certs, err := cert.ParseCertsPEM(certData)
if err != nil {
t.Fatalf("failed to parse certificate: %v", err)
}
if len(certs) != 1 {
t.Fatalf("expected one certificate")
}
crt := certs[0]
if crt.Subject.CommonName != "system:node:k-a-node-s36b" {
t.Errorf("expected common name of 'system:node:k-a-node-s36b', but got: %v", certs[0].Subject.CommonName)
}
if !reflect.DeepEqual(crt.Subject.Organization, []string{"system:nodes"}) {
t.Errorf("expected organization to be [system:nodes] but got: %v", crt.Subject.Organization)
}
if crt.KeyUsage != x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment {
t.Errorf("bad key usage")
}
if !reflect.DeepEqual(crt.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) {
t.Errorf("bad extended key usage")
}
}

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC9zCCAd+gAwIBAgIJAOWJ8tWNUIsZMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
BAMMB2t1YmUtY2EwHhcNMTYxMjIyMDAyNTI5WhcNNDQwNTA5MDAyNTI5WjASMRAw
DgYDVQQDDAdrdWJlLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
1HK1d2p7N7UC6px8lVtABw8jPpVyNYjrJmI+TKTTdCgWGsUTFMCw4t4Q/KQDDlvB
P19uPhbfp8aLwOWXBCxOPZzlM2mAEjSUgKjbyGCW/8vaXa2VgQm3tKZdydKiFvIo
fEsNA+58w8A0WWEB8wYFcdCt8uPyQ0ws/TxE+WW3u7EPlC0/inIX9JqeZZMpDk3N
lHEv/pGEjQmoet/hBwGHq9PKepkN5/V6rrSADJ5I4Uklp2f7G9MCP/zV8xKfs0lK
CMoJsIPK3nL9N3C0rqBQPfcyKE2fnEkxC3UVZA8brvLTkBfOgmM2eVg/nauU1ejv
zOJL7tDwUioLriw2hiGrFwIDAQABo1AwTjAdBgNVHQ4EFgQUbGJxJeW7BgZ4xSmW
d3Aw3gq8YZUwHwYDVR0jBBgwFoAUbGJxJeW7BgZ4xSmWd3Aw3gq8YZUwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAunzpYAxpzguzxG83pK5n3ObsGDwO
78d38qX1VRvMLPvioZxYgquqqFPdLI3xe8b8KdZNzb65549tgjAI17tTKGTRgJu5
yzLU1tO4vNaAFecMCtPvElYfkrAv2vbGCVJ1bYKTnjdu3083jG3sY9TDj0364A57
lNwKEd5uxHGWg4H+NbyHkDqfKmllzLvJ9XjSWBPmNVLSW50hV+h9fUXgz9LN+qVY
VEDfAEWqb6PVy9ANw8A8QLnuSRxbd7hAigtlC4MwzYJ6tyFIIH6bCIgfoZuA+brm
WGcpIxl4fKEGafSgjsK/6Yhb61mkhHmG16mzEUZNkNsjiYJuF2QxpOlQrw==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA1HK1d2p7N7UC6px8lVtABw8jPpVyNYjrJmI+TKTTdCgWGsUT
FMCw4t4Q/KQDDlvBP19uPhbfp8aLwOWXBCxOPZzlM2mAEjSUgKjbyGCW/8vaXa2V
gQm3tKZdydKiFvIofEsNA+58w8A0WWEB8wYFcdCt8uPyQ0ws/TxE+WW3u7EPlC0/
inIX9JqeZZMpDk3NlHEv/pGEjQmoet/hBwGHq9PKepkN5/V6rrSADJ5I4Uklp2f7
G9MCP/zV8xKfs0lKCMoJsIPK3nL9N3C0rqBQPfcyKE2fnEkxC3UVZA8brvLTkBfO
gmM2eVg/nauU1ejvzOJL7tDwUioLriw2hiGrFwIDAQABAoIBAFJCmEFE2bEYRajS
LusmCgSxt9PjyfUwrtyN7dF/gODZJLX42QqQEe3GTo2EdCp7HLiNGwKvmKo+Fp76
Rx82iJUSyyy9DPn/ogCvYWqU++LP7B2ZuOnd+WPZhzc+d8Sqv0JhTQjYrzaclaiG
B1syWalYRAJogMXOGR102MA4wovJrlHFuTVSWiDe0uguLxyjoTMIRqbib9ZAMSLX
bfcM2abGpXgq10abda3KKAJbZyr2fnBvqKTs4a4zYeHJpQT+NBPMiryb2WnPFg+b
93nrjDxUtPsx8NJz6HGkSQLagXkZX2J1JpT8loaNIdyQHab1LNXptc84LR8xxusy
bs5NowECgYEA+j+SwVgeC+NCUIfxr3F9zPAD9A0Tk3gD4z+j0opfLIMghX4jtK0e
9fQyglecAbojlkEUk/js5IVZ0IIhBNPWXxKtdShZO7EmJ6Z5IEmFrZK1xUomYBa2
BfysqSAkxVLsTDIfI0Q4DHQNDOV+iY3j8WoaR51cXr+IY+mYBGSNI80CgYEA2VS5
X5QHDxoh3r5ORiyab3ciubEofJ29D3NR1tCe9ZgSYRV5Y7T/4KPpZdpsEX/ydYD6
X4DyURuYNK7PUR8DSlX7/VuMzHThqGJMaT0LE+alU4bruiad33X1WXgtcPTGCic0
8il50TZTgba0CwxuCO1eVb3IijwgJBX/byM67nMCgYEA7As1KSwtwzbMoVtpa/xY
Fgu7HuOKuIn22M55fylH1puk/GXb1huJ3aNGVU2/+J0T3jFq8JxXDsJ90kA8Vupe
BXV/qceyS6yv+ax8Cilvbya4T+y+P9qMPR912V1Zccri2ohYeJJrb8uzV5vM/ICb
JmbXfP+AVlrBksSOwG37920CgYEAsSi2X6o8QtxLhdZd2ihbz8cu4G4AkezHhAO+
T70KBytquAcYR+Xwu38CMEvn0jAZRh3YeueTH/i9jxx81STRutPysSni0Xvpwyg2
H4dqM1PNqxQNrlXyVYlDciZb7HsrwHULXOfgbGG7mr6Db4o3XEGap4woID84+BGS
glcWn+8CgYEA36uulmZcodfet04qQvlDtr1d7mwLdTR/JAO0ZBIgFH7eGZdEVh8O
DoTJTdSSJGiv8J35PwEXfhKHjhgOjDocLYu+yCOwVj7jRdHqlDS1BaE36Hzdw0rb
mWkBRMGJtGhzhoRJEFHAnoLXc9danRfnHwVR58drlf7bjR5I9eU9u1I=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,8 @@
-----BEGIN CERTIFICATE REQUEST-----
MIH1MIGdAgEAMDsxFTATBgNVBAoTDHN5c3RlbTpub2RlczEiMCAGA1UEAxMZc3lz
dGVtOm5vZGU6ay1hLW5vZGUtczM2YjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BJbxa5Y8SrUJVHpOoWD5ceqH+5R9mjIhwVP2sqfTcLkjvbitzOiLlxSq/LwJ+qq7
kVpf9f3GopZVhRWbYSCg0YGgADAKBggqhkjOPQQDAgNHADBEAiAabb6XFtPOJUCQ
+84NhxLEvPANhrtwFq3Q0qFZ9TzH5QIgc/697RTTcbri2lVj+10dLFIC3VYJ7br4
QjA7haCYXrA=
-----END CERTIFICATE REQUEST-----

View File

@ -8930,6 +8930,20 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
Format: "byte",
},
},
"usages": {
SchemaProps: spec.SchemaProps{
Description: "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
"username": {
SchemaProps: spec.SchemaProps{
Description: "Information about the requesting user (if relevant) See user.Info interface for details",