Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1418)

Delta Between Two Patch Sets: ssh/certs.go

Issue 14540051: code review 14540051: go.crypto/ssh: Add certificate verification, step up su... (Closed)
Left Patch Set: diff -r 5ff5636e18c9 https://code.google.com/p/go.crypto Created 11 years, 5 months ago
Right Patch Set: diff -r 5ff5636e18c9 https://code.google.com/p/go.crypto Created 11 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | ssh/certs_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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
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 }
LEFTRIGHT
« no previous file | ssh/certs_test.go » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b