certs.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "time"
  7. )
  8. // These constants from [PROTOCOL.certkeys] represent the algorithm names
  9. // for certificate types supported by this package.
  10. const (
  11. CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
  12. CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
  13. CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
  14. CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
  15. CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
  16. )
  17. // Certificate types are used to specify whether a certificate is for identification
  18. // of a user or a host. Current identities are defined in [PROTOCOL.certkeys].
  19. const (
  20. UserCert = 1
  21. HostCert = 2
  22. )
  23. type signature struct {
  24. Format string
  25. Blob []byte
  26. }
  27. type tuple struct {
  28. Name string
  29. Data string
  30. }
  31. const (
  32. maxUint64 = 1<<64 - 1
  33. maxInt64 = 1<<63 - 1
  34. )
  35. // CertTime represents an unsigned 64-bit time value in seconds starting from
  36. // UNIX epoch. We use CertTime instead of time.Time in order to properly handle
  37. // the "infinite" time value ^0, which would become negative when expressed as
  38. // an int64.
  39. type CertTime uint64
  40. func (ct CertTime) Time() time.Time {
  41. if ct > maxInt64 {
  42. return time.Unix(maxInt64, 0)
  43. }
  44. return time.Unix(int64(ct), 0)
  45. }
  46. func (ct CertTime) IsInfinite() bool {
  47. return ct == maxUint64
  48. }
  49. // An OpenSSHCertV01 represents an OpenSSH certificate as defined in
  50. // [PROTOCOL.certkeys]?rev=1.8.
  51. type OpenSSHCertV01 struct {
  52. Nonce []byte
  53. Key PublicKey
  54. Serial uint64
  55. Type uint32
  56. KeyId string
  57. ValidPrincipals []string
  58. ValidAfter, ValidBefore CertTime
  59. CriticalOptions []tuple
  60. Extensions []tuple
  61. Reserved []byte
  62. SignatureKey PublicKey
  63. Signature *signature
  64. }
  65. // validateOpenSSHCertV01Signature uses the cert's SignatureKey to verify that
  66. // the cert's Signature.Blob is the result of signing the cert bytes starting
  67. // from the algorithm string and going up to and including the SignatureKey.
  68. func validateOpenSSHCertV01Signature(cert *OpenSSHCertV01) bool {
  69. return cert.SignatureKey.Verify(cert.BytesForSigning(), cert.Signature.Blob)
  70. }
  71. var certAlgoNames = map[string]string{
  72. KeyAlgoRSA: CertAlgoRSAv01,
  73. KeyAlgoDSA: CertAlgoDSAv01,
  74. KeyAlgoECDSA256: CertAlgoECDSA256v01,
  75. KeyAlgoECDSA384: CertAlgoECDSA384v01,
  76. KeyAlgoECDSA521: CertAlgoECDSA521v01,
  77. }
  78. // certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
  79. // Panics if a non-certificate algorithm is passed.
  80. func certToPrivAlgo(algo string) string {
  81. for privAlgo, pubAlgo := range certAlgoNames {
  82. if pubAlgo == algo {
  83. return privAlgo
  84. }
  85. }
  86. panic("unknown cert algorithm")
  87. }
  88. func (cert *OpenSSHCertV01) marshal(includeAlgo, includeSig bool) []byte {
  89. algoName := cert.PublicKeyAlgo()
  90. pubKey := cert.Key.Marshal()
  91. sigKey := MarshalPublicKey(cert.SignatureKey)
  92. var length int
  93. if includeAlgo {
  94. length += stringLength(len(algoName))
  95. }
  96. length += stringLength(len(cert.Nonce))
  97. length += len(pubKey)
  98. length += 8 // Length of Serial
  99. length += 4 // Length of Type
  100. length += stringLength(len(cert.KeyId))
  101. length += lengthPrefixedNameListLength(cert.ValidPrincipals)
  102. length += 8 // Length of ValidAfter
  103. length += 8 // Length of ValidBefore
  104. length += tupleListLength(cert.CriticalOptions)
  105. length += tupleListLength(cert.Extensions)
  106. length += stringLength(len(cert.Reserved))
  107. length += stringLength(len(sigKey))
  108. if includeSig {
  109. length += signatureLength(cert.Signature)
  110. }
  111. ret := make([]byte, length)
  112. r := ret
  113. if includeAlgo {
  114. r = marshalString(r, []byte(algoName))
  115. }
  116. r = marshalString(r, cert.Nonce)
  117. copy(r, pubKey)
  118. r = r[len(pubKey):]
  119. r = marshalUint64(r, cert.Serial)
  120. r = marshalUint32(r, cert.Type)
  121. r = marshalString(r, []byte(cert.KeyId))
  122. r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals)
  123. r = marshalUint64(r, uint64(cert.ValidAfter))
  124. r = marshalUint64(r, uint64(cert.ValidBefore))
  125. r = marshalTupleList(r, cert.CriticalOptions)
  126. r = marshalTupleList(r, cert.Extensions)
  127. r = marshalString(r, cert.Reserved)
  128. r = marshalString(r, sigKey)
  129. if includeSig {
  130. r = marshalSignature(r, cert.Signature)
  131. }
  132. if len(r) > 0 {
  133. panic("ssh: internal error, marshaling certificate did not fill the entire buffer")
  134. }
  135. return ret
  136. }
  137. func (cert *OpenSSHCertV01) BytesForSigning() []byte {
  138. return cert.marshal(true, false)
  139. }
  140. func (cert *OpenSSHCertV01) Marshal() []byte {
  141. return cert.marshal(false, true)
  142. }
  143. func (c *OpenSSHCertV01) PublicKeyAlgo() string {
  144. algo, ok := certAlgoNames[c.Key.PublicKeyAlgo()]
  145. if !ok {
  146. panic("unknown cert key type")
  147. }
  148. return algo
  149. }
  150. func (c *OpenSSHCertV01) PrivateKeyAlgo() string {
  151. return c.Key.PrivateKeyAlgo()
  152. }
  153. func (c *OpenSSHCertV01) Verify(data []byte, sig []byte) bool {
  154. return c.Key.Verify(data, sig)
  155. }
  156. func parseOpenSSHCertV01(in []byte, algo string) (out *OpenSSHCertV01, rest []byte, ok bool) {
  157. cert := new(OpenSSHCertV01)
  158. if cert.Nonce, in, ok = parseString(in); !ok {
  159. return
  160. }
  161. privAlgo := certToPrivAlgo(algo)
  162. cert.Key, in, ok = parsePubKey(in, privAlgo)
  163. if !ok {
  164. return
  165. }
  166. // We test PublicKeyAlgo to make sure we don't use some weird sub-cert.
  167. if cert.Key.PublicKeyAlgo() != privAlgo {
  168. ok = false
  169. return
  170. }
  171. if cert.Serial, in, ok = parseUint64(in); !ok {
  172. return
  173. }
  174. if cert.Type, in, ok = parseUint32(in); !ok {
  175. return
  176. }
  177. keyId, in, ok := parseString(in)
  178. if !ok {
  179. return
  180. }
  181. cert.KeyId = string(keyId)
  182. if cert.ValidPrincipals, in, ok = parseLengthPrefixedNameList(in); !ok {
  183. return
  184. }
  185. va, in, ok := parseUint64(in)
  186. if !ok {
  187. return
  188. }
  189. cert.ValidAfter = CertTime(va)
  190. vb, in, ok := parseUint64(in)
  191. if !ok {
  192. return
  193. }
  194. cert.ValidBefore = CertTime(vb)
  195. if cert.CriticalOptions, in, ok = parseTupleList(in); !ok {
  196. return
  197. }
  198. if cert.Extensions, in, ok = parseTupleList(in); !ok {
  199. return
  200. }
  201. if cert.Reserved, in, ok = parseString(in); !ok {
  202. return
  203. }
  204. sigKey, in, ok := parseString(in)
  205. if !ok {
  206. return
  207. }
  208. if cert.SignatureKey, _, ok = ParsePublicKey(sigKey); !ok {
  209. return
  210. }
  211. if cert.Signature, in, ok = parseSignature(in); !ok {
  212. return
  213. }
  214. ok = true
  215. return cert, in, ok
  216. }
  217. func lengthPrefixedNameListLength(namelist []string) int {
  218. length := 4 // length prefix for list
  219. for _, name := range namelist {
  220. length += 4 // length prefix for name
  221. length += len(name)
  222. }
  223. return length
  224. }
  225. func marshalLengthPrefixedNameList(to []byte, namelist []string) []byte {
  226. length := uint32(lengthPrefixedNameListLength(namelist) - 4)
  227. to = marshalUint32(to, length)
  228. for _, name := range namelist {
  229. to = marshalString(to, []byte(name))
  230. }
  231. return to
  232. }
  233. func parseLengthPrefixedNameList(in []byte) (out []string, rest []byte, ok bool) {
  234. list, rest, ok := parseString(in)
  235. if !ok {
  236. return
  237. }
  238. for len(list) > 0 {
  239. var next []byte
  240. if next, list, ok = parseString(list); !ok {
  241. return nil, nil, false
  242. }
  243. out = append(out, string(next))
  244. }
  245. ok = true
  246. return
  247. }
  248. func tupleListLength(tupleList []tuple) int {
  249. length := 4 // length prefix for list
  250. for _, t := range tupleList {
  251. length += 4 // length prefix for t.Name
  252. length += len(t.Name)
  253. length += 4 // length prefix for t.Data
  254. length += len(t.Data)
  255. }
  256. return length
  257. }
  258. func marshalTupleList(to []byte, tuplelist []tuple) []byte {
  259. length := uint32(tupleListLength(tuplelist) - 4)
  260. to = marshalUint32(to, length)
  261. for _, t := range tuplelist {
  262. to = marshalString(to, []byte(t.Name))
  263. to = marshalString(to, []byte(t.Data))
  264. }
  265. return to
  266. }
  267. func parseTupleList(in []byte) (out []tuple, rest []byte, ok bool) {
  268. list, rest, ok := parseString(in)
  269. if !ok {
  270. return
  271. }
  272. for len(list) > 0 {
  273. var name, data []byte
  274. var ok bool
  275. name, list, ok = parseString(list)
  276. if !ok {
  277. return nil, nil, false
  278. }
  279. data, list, ok = parseString(list)
  280. if !ok {
  281. return nil, nil, false
  282. }
  283. out = append(out, tuple{string(name), string(data)})
  284. }
  285. ok = true
  286. return
  287. }
  288. func signatureLength(sig *signature) int {
  289. length := 4 // length prefix for signature
  290. length += stringLength(len(sig.Format))
  291. length += stringLength(len(sig.Blob))
  292. return length
  293. }
  294. func marshalSignature(to []byte, sig *signature) []byte {
  295. length := uint32(signatureLength(sig) - 4)
  296. to = marshalUint32(to, length)
  297. to = marshalString(to, []byte(sig.Format))
  298. to = marshalString(to, sig.Blob)
  299. return to
  300. }
  301. func parseSignatureBody(in []byte) (out *signature, rest []byte, ok bool) {
  302. var format []byte
  303. if format, in, ok = parseString(in); !ok {
  304. return
  305. }
  306. out = &signature{
  307. Format: string(format),
  308. }
  309. if out.Blob, in, ok = parseString(in); !ok {
  310. return
  311. }
  312. return out, in, ok
  313. }
  314. func parseSignature(in []byte) (out *signature, rest []byte, ok bool) {
  315. var sigBytes []byte
  316. if sigBytes, rest, ok = parseString(in); !ok {
  317. return
  318. }
  319. out, sigBytes, ok = parseSignatureBody(sigBytes)
  320. if !ok || len(sigBytes) > 0 {
  321. return nil, nil, false
  322. }
  323. return
  324. }