LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ssh | 5 package ssh |
6 | 6 |
7 import ( | 7 import ( |
8 "time" | 8 "time" |
9 ) | 9 ) |
10 | 10 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 KeyId string | 45 KeyId string |
46 ValidPrincipals []string | 46 ValidPrincipals []string |
47 ValidAfter, ValidBefore time.Time | 47 ValidAfter, ValidBefore time.Time |
48 CriticalOptions []tuple | 48 CriticalOptions []tuple |
49 Extensions []tuple | 49 Extensions []tuple |
50 Reserved []byte | 50 Reserved []byte |
51 SignatureKey PublicKey | 51 SignatureKey PublicKey |
52 Signature *signature | 52 Signature *signature |
53 } | 53 } |
54 | 54 |
55 // validateOpenSSHCertV01Signature uses the cert's SignatureKey to verify that t
he | 55 // validateOpenSSHCertV01Signature uses the cert's SignatureKey to verify that |
56 // cert's Signature.Blob is the result of signing the cert bytes starting from | 56 // the cert's Signature.Blob is the result of signing the cert bytes starting |
57 // the algorithm string and going up to and including the SignatureKey. | 57 // from the algorithm string and going up to and including the SignatureKey. |
58 func validateOpenSSHCertV01Signature(cert *OpenSSHCertV01) bool { | 58 func validateOpenSSHCertV01Signature(cert *OpenSSHCertV01) bool { |
59 return cert.SignatureKey.Verify(cert.BytesForSigning(), cert.Signature.B
lob) | 59 return cert.SignatureKey.Verify(cert.BytesForSigning(), cert.Signature.B
lob) |
60 } | 60 } |
61 | 61 |
62 var certAlgoNames = map[string]string{ | 62 var certAlgoNames = map[string]string{ |
63 KeyAlgoRSA: CertAlgoRSAv01, | 63 KeyAlgoRSA: CertAlgoRSAv01, |
64 KeyAlgoDSA: CertAlgoDSAv01, | 64 KeyAlgoDSA: CertAlgoDSAv01, |
65 KeyAlgoECDSA256: CertAlgoECDSA256v01, | 65 KeyAlgoECDSA256: CertAlgoECDSA256v01, |
66 KeyAlgoECDSA384: CertAlgoECDSA384v01, | 66 KeyAlgoECDSA384: CertAlgoECDSA384v01, |
67 KeyAlgoECDSA521: CertAlgoECDSA521v01, | 67 KeyAlgoECDSA521: CertAlgoECDSA521v01, |
68 } | 68 } |
69 | 69 |
70 // certToPrivAlgo returns the underlying algorithm for a certificate algorithm. | 70 // certToPrivAlgo returns the underlying algorithm for a certificate algorithm. |
71 // Panics if a non-certificate algorithm is passed. | 71 // Panics if a non-certificate algorithm is passed. |
72 func certToPrivAlgo(algo string) string { | 72 func certToPrivAlgo(algo string) string { |
73 for privAlgo, pubAlgo := range certAlgoNames { | 73 for privAlgo, pubAlgo := range certAlgoNames { |
74 if pubAlgo == algo { | 74 if pubAlgo == algo { |
75 return privAlgo | 75 return privAlgo |
76 } | 76 } |
77 } | 77 } |
78 panic("unknown cert algorithm") | 78 panic("unknown cert algorithm") |
79 } | 79 } |
80 | 80 |
81 func (cert *OpenSSHCertV01) BytesForSigning() []byte { | 81 func (cert *OpenSSHCertV01) marshal(includeAlgo, includeSig bool) []byte { |
82 algoName := cert.PublicKeyAlgo() | 82 algoName := cert.PublicKeyAlgo() |
83 pubKey := cert.Key.Marshal() | 83 pubKey := cert.Key.Marshal() |
84 sigKey := MarshalPublicKey(cert.SignatureKey) | 84 sigKey := MarshalPublicKey(cert.SignatureKey) |
85 | 85 |
86 » length := stringLength(len(algoName)) | 86 » var length int |
| 87 » if includeAlgo { |
| 88 » » length += stringLength(len(algoName)) |
| 89 » } |
87 length += stringLength(len(cert.Nonce)) | 90 length += stringLength(len(cert.Nonce)) |
88 length += len(pubKey) | 91 length += len(pubKey) |
89 length += 8 // Length of Serial | 92 length += 8 // Length of Serial |
90 length += 4 // Length of Type | 93 length += 4 // Length of Type |
91 length += stringLength(len(cert.KeyId)) | 94 length += stringLength(len(cert.KeyId)) |
92 length += lengthPrefixedNameListLength(cert.ValidPrincipals) | 95 length += lengthPrefixedNameListLength(cert.ValidPrincipals) |
93 length += 8 // Length of ValidAfter | 96 length += 8 // Length of ValidAfter |
94 length += 8 // Length of ValidBefore | 97 length += 8 // Length of ValidBefore |
95 length += tupleListLength(cert.CriticalOptions) | 98 length += tupleListLength(cert.CriticalOptions) |
96 length += tupleListLength(cert.Extensions) | 99 length += tupleListLength(cert.Extensions) |
97 length += stringLength(len(cert.Reserved)) | 100 length += stringLength(len(cert.Reserved)) |
98 length += stringLength(len(sigKey)) | 101 length += stringLength(len(sigKey)) |
| 102 if includeSig { |
| 103 length += signatureLength(cert.Signature) |
| 104 } |
99 | 105 |
100 ret := make([]byte, length) | 106 ret := make([]byte, length) |
101 » r := marshalString(ret, []byte(algoName)) | 107 » r := ret |
| 108 » if includeAlgo { |
| 109 » » r = marshalString(r, []byte(algoName)) |
| 110 » } |
102 r = marshalString(r, cert.Nonce) | 111 r = marshalString(r, cert.Nonce) |
103 copy(r, pubKey) | 112 copy(r, pubKey) |
104 r = r[len(pubKey):] | 113 r = r[len(pubKey):] |
105 r = marshalUint64(r, cert.Serial) | 114 r = marshalUint64(r, cert.Serial) |
106 r = marshalUint32(r, cert.Type) | 115 r = marshalUint32(r, cert.Type) |
107 r = marshalString(r, []byte(cert.KeyId)) | 116 r = marshalString(r, []byte(cert.KeyId)) |
108 r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals) | 117 r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals) |
109 r = marshalUint64(r, uint64(cert.ValidAfter.Unix())) | 118 r = marshalUint64(r, uint64(cert.ValidAfter.Unix())) |
110 r = marshalUint64(r, uint64(cert.ValidBefore.Unix())) | 119 r = marshalUint64(r, uint64(cert.ValidBefore.Unix())) |
111 r = marshalTupleList(r, cert.CriticalOptions) | 120 r = marshalTupleList(r, cert.CriticalOptions) |
112 r = marshalTupleList(r, cert.Extensions) | 121 r = marshalTupleList(r, cert.Extensions) |
113 r = marshalString(r, cert.Reserved) | 122 r = marshalString(r, cert.Reserved) |
114 r = marshalString(r, sigKey) | 123 r = marshalString(r, sigKey) |
| 124 if includeSig { |
| 125 r = marshalSignature(r, cert.Signature) |
| 126 } |
115 if len(r) > 0 { | 127 if len(r) > 0 { |
116 panic("ssh: internal error, marshaling certificate did not fill
the entire buffer") | 128 panic("ssh: internal error, marshaling certificate did not fill
the entire buffer") |
117 } | 129 } |
118 return ret | 130 return ret |
| 131 } |
| 132 |
| 133 func (cert *OpenSSHCertV01) BytesForSigning() []byte { |
| 134 return cert.marshal(true, false) |
| 135 } |
| 136 |
| 137 func (cert *OpenSSHCertV01) Marshal() []byte { |
| 138 return cert.marshal(false, true) |
119 } | 139 } |
120 | 140 |
121 func (c *OpenSSHCertV01) PublicKeyAlgo() string { | 141 func (c *OpenSSHCertV01) PublicKeyAlgo() string { |
122 algo, ok := certAlgoNames[c.Key.PublicKeyAlgo()] | 142 algo, ok := certAlgoNames[c.Key.PublicKeyAlgo()] |
123 if !ok { | 143 if !ok { |
124 panic("unknown cert key type") | 144 panic("unknown cert key type") |
125 } | 145 } |
126 return algo | 146 return algo |
127 } | 147 } |
128 | 148 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 if cert.SignatureKey, _, ok = ParsePublicKey(sigKey); !ok { | 222 if cert.SignatureKey, _, ok = ParsePublicKey(sigKey); !ok { |
203 return | 223 return |
204 } | 224 } |
205 | 225 |
206 if cert.Signature, in, ok = parseSignature(in); !ok { | 226 if cert.Signature, in, ok = parseSignature(in); !ok { |
207 return | 227 return |
208 } | 228 } |
209 | 229 |
210 ok = true | 230 ok = true |
211 return cert, in, ok | 231 return cert, in, ok |
212 } | |
213 | |
214 func (cert *OpenSSHCertV01) Marshal() []byte { | |
215 pubKey := cert.Key.Marshal() | |
216 sigKey := MarshalPublicKey(cert.SignatureKey) | |
217 | |
218 length := stringLength(len(cert.Nonce)) | |
219 length += len(pubKey) | |
220 length += 8 // Length of Serial | |
221 length += 4 // Length of Type | |
222 length += stringLength(len(cert.KeyId)) | |
223 length += lengthPrefixedNameListLength(cert.ValidPrincipals) | |
224 length += 8 // Length of ValidAfter | |
225 length += 8 // Length of ValidBefore | |
226 length += tupleListLength(cert.CriticalOptions) | |
227 length += tupleListLength(cert.Extensions) | |
228 length += stringLength(len(cert.Reserved)) | |
229 length += stringLength(len(sigKey)) | |
230 length += signatureLength(cert.Signature) | |
231 | |
232 ret := make([]byte, length) | |
233 r := marshalString(ret, cert.Nonce) | |
234 copy(r, pubKey) | |
235 r = r[len(pubKey):] | |
236 r = marshalUint64(r, cert.Serial) | |
237 r = marshalUint32(r, cert.Type) | |
238 r = marshalString(r, []byte(cert.KeyId)) | |
239 r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals) | |
240 r = marshalUint64(r, uint64(cert.ValidAfter.Unix())) | |
241 r = marshalUint64(r, uint64(cert.ValidBefore.Unix())) | |
242 r = marshalTupleList(r, cert.CriticalOptions) | |
243 r = marshalTupleList(r, cert.Extensions) | |
244 r = marshalString(r, cert.Reserved) | |
245 r = marshalString(r, sigKey) | |
246 r = marshalSignature(r, cert.Signature) | |
247 if len(r) > 0 { | |
248 panic("ssh: internal error, marshaling certificate did not fill
the entire buffer") | |
249 } | |
250 return ret | |
251 } | 232 } |
252 | 233 |
253 func lengthPrefixedNameListLength(namelist []string) int { | 234 func lengthPrefixedNameListLength(namelist []string) int { |
254 length := 4 // length prefix for list | 235 length := 4 // length prefix for list |
255 for _, name := range namelist { | 236 for _, name := range namelist { |
256 length += 4 // length prefix for name | 237 length += 4 // length prefix for name |
257 length += len(name) | 238 length += len(name) |
258 } | 239 } |
259 return length | 240 return length |
260 } | 241 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 if sigBytes, rest, ok = parseString(in); !ok { | 347 if sigBytes, rest, ok = parseString(in); !ok { |
367 return | 348 return |
368 } | 349 } |
369 | 350 |
370 out, sigBytes, ok = parseSignatureBody(sigBytes) | 351 out, sigBytes, ok = parseSignatureBody(sigBytes) |
371 if !ok || len(sigBytes) > 0 { | 352 if !ok || len(sigBytes) > 0 { |
372 return nil, nil, false | 353 return nil, nil, false |
373 } | 354 } |
374 return | 355 return |
375 } | 356 } |
LEFT | RIGHT |