certs.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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. "crypto/dsa"
  7. "crypto/ecdsa"
  8. "crypto/rsa"
  9. "time"
  10. )
  11. // String constants in [PROTOCOL.certkeys] for certificate algorithm names.
  12. const (
  13. CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
  14. CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
  15. CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
  16. CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
  17. CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
  18. )
  19. // Certificate types are used to specify whether a certificate is for identification
  20. // of a user or a host. Current identities are defined in [PROTOCOL.certkeys].
  21. const (
  22. UserCert = 1
  23. HostCert = 2
  24. )
  25. type signature struct {
  26. Format string
  27. Blob []byte
  28. }
  29. type tuple struct {
  30. Name string
  31. Data string
  32. }
  33. // An OpenSSHCertV01 represents an OpenSSH certificate as defined in
  34. // [PROTOCOL.certkeys]?rev=1.8.
  35. type OpenSSHCertV01 struct {
  36. Nonce []byte
  37. Key interface{} // rsa, dsa, or ecdsa *PublicKey
  38. Serial uint64
  39. Type uint32
  40. KeyId string
  41. ValidPrincipals []string
  42. ValidAfter, ValidBefore time.Time
  43. CriticalOptions []tuple
  44. Extensions []tuple
  45. Reserved []byte
  46. SignatureKey interface{} // rsa, dsa, or ecdsa *PublicKey
  47. Signature *signature
  48. }
  49. func parseOpenSSHCertV01(in []byte, algo string) (out *OpenSSHCertV01, rest []byte, ok bool) {
  50. cert := new(OpenSSHCertV01)
  51. if cert.Nonce, in, ok = parseString(in); !ok {
  52. return
  53. }
  54. switch algo {
  55. case CertAlgoRSAv01:
  56. var rsaPubKey *rsa.PublicKey
  57. if rsaPubKey, in, ok = parseRSA(in); !ok {
  58. return
  59. }
  60. cert.Key = rsaPubKey
  61. case CertAlgoDSAv01:
  62. var dsaPubKey *dsa.PublicKey
  63. if dsaPubKey, in, ok = parseDSA(in); !ok {
  64. return
  65. }
  66. cert.Key = dsaPubKey
  67. case CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
  68. var ecdsaPubKey *ecdsa.PublicKey
  69. if ecdsaPubKey, in, ok = parseECDSA(in); !ok {
  70. return
  71. }
  72. cert.Key = ecdsaPubKey
  73. default:
  74. ok = false
  75. return
  76. }
  77. if cert.Serial, in, ok = parseUint64(in); !ok {
  78. return
  79. }
  80. if cert.Type, in, ok = parseUint32(in); !ok || cert.Type != UserCert && cert.Type != HostCert {
  81. return
  82. }
  83. keyId, in, ok := parseString(in)
  84. if !ok {
  85. return
  86. }
  87. cert.KeyId = string(keyId)
  88. if cert.ValidPrincipals, in, ok = parseLengthPrefixedNameList(in); !ok {
  89. return
  90. }
  91. va, in, ok := parseUint64(in)
  92. if !ok {
  93. return
  94. }
  95. cert.ValidAfter = time.Unix(int64(va), 0)
  96. vb, in, ok := parseUint64(in)
  97. if !ok {
  98. return
  99. }
  100. cert.ValidBefore = time.Unix(int64(vb), 0)
  101. if cert.CriticalOptions, in, ok = parseTupleList(in); !ok {
  102. return
  103. }
  104. if cert.Extensions, in, ok = parseTupleList(in); !ok {
  105. return
  106. }
  107. if cert.Reserved, in, ok = parseString(in); !ok {
  108. return
  109. }
  110. sigKey, in, ok := parseString(in)
  111. if !ok {
  112. return
  113. }
  114. if cert.SignatureKey, _, ok = parsePubKey(sigKey); !ok {
  115. return
  116. }
  117. if cert.Signature, in, ok = parseSignature(in); !ok {
  118. return
  119. }
  120. ok = true
  121. return cert, in, ok
  122. }
  123. func marshalOpenSSHCertV01(cert *OpenSSHCertV01) []byte {
  124. var pubKey []byte
  125. switch cert.Key.(type) {
  126. case *rsa.PublicKey:
  127. k := cert.Key.(*rsa.PublicKey)
  128. pubKey = marshalPubRSA(k)
  129. case *dsa.PublicKey:
  130. k := cert.Key.(*dsa.PublicKey)
  131. pubKey = marshalPubDSA(k)
  132. case *ecdsa.PublicKey:
  133. k := cert.Key.(*ecdsa.PublicKey)
  134. pubKey = marshalPubECDSA(k)
  135. default:
  136. panic("ssh: unknown public key type in cert")
  137. }
  138. sigKey := serializePublickey(cert.SignatureKey)
  139. length := stringLength(len(cert.Nonce))
  140. length += len(pubKey)
  141. length += 8 // Length of Serial
  142. length += 4 // Length of Type
  143. length += stringLength(len(cert.KeyId))
  144. length += lengthPrefixedNameListLength(cert.ValidPrincipals)
  145. length += 8 // Length of ValidAfter
  146. length += 8 // Length of ValidBefore
  147. length += tupleListLength(cert.CriticalOptions)
  148. length += tupleListLength(cert.Extensions)
  149. length += stringLength(len(cert.Reserved))
  150. length += stringLength(len(sigKey))
  151. length += signatureLength(cert.Signature)
  152. ret := make([]byte, length)
  153. r := marshalString(ret, cert.Nonce)
  154. copy(r, pubKey)
  155. r = r[len(pubKey):]
  156. r = marshalUint64(r, cert.Serial)
  157. r = marshalUint32(r, cert.Type)
  158. r = marshalString(r, []byte(cert.KeyId))
  159. r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals)
  160. r = marshalUint64(r, uint64(cert.ValidAfter.Unix()))
  161. r = marshalUint64(r, uint64(cert.ValidBefore.Unix()))
  162. r = marshalTupleList(r, cert.CriticalOptions)
  163. r = marshalTupleList(r, cert.Extensions)
  164. r = marshalString(r, cert.Reserved)
  165. r = marshalString(r, sigKey)
  166. r = marshalSignature(r, cert.Signature)
  167. if len(r) > 0 {
  168. panic("internal error")
  169. }
  170. return ret
  171. }
  172. func lengthPrefixedNameListLength(namelist []string) int {
  173. length := 4 // length prefix for list
  174. for _, name := range namelist {
  175. length += 4 // length prefix for name
  176. length += len(name)
  177. }
  178. return length
  179. }
  180. func marshalLengthPrefixedNameList(to []byte, namelist []string) []byte {
  181. length := uint32(lengthPrefixedNameListLength(namelist) - 4)
  182. to = marshalUint32(to, length)
  183. for _, name := range namelist {
  184. to = marshalString(to, []byte(name))
  185. }
  186. return to
  187. }
  188. func parseLengthPrefixedNameList(in []byte) (out []string, rest []byte, ok bool) {
  189. list, rest, ok := parseString(in)
  190. if !ok {
  191. return
  192. }
  193. for len(list) > 0 {
  194. var next []byte
  195. if next, list, ok = parseString(list); !ok {
  196. return nil, nil, false
  197. }
  198. out = append(out, string(next))
  199. }
  200. ok = true
  201. return
  202. }
  203. func tupleListLength(tupleList []tuple) int {
  204. length := 4 // length prefix for list
  205. for _, t := range tupleList {
  206. length += 4 // length prefix for t.Name
  207. length += len(t.Name)
  208. length += 4 // length prefix for t.Data
  209. length += len(t.Data)
  210. }
  211. return length
  212. }
  213. func marshalTupleList(to []byte, tuplelist []tuple) []byte {
  214. length := uint32(tupleListLength(tuplelist) - 4)
  215. to = marshalUint32(to, length)
  216. for _, t := range tuplelist {
  217. to = marshalString(to, []byte(t.Name))
  218. to = marshalString(to, []byte(t.Data))
  219. }
  220. return to
  221. }
  222. func parseTupleList(in []byte) (out []tuple, rest []byte, ok bool) {
  223. list, rest, ok := parseString(in)
  224. if !ok {
  225. return
  226. }
  227. for len(list) > 0 {
  228. var name, data []byte
  229. var ok bool
  230. name, list, ok = parseString(list)
  231. if !ok {
  232. return nil, nil, false
  233. }
  234. data, list, ok = parseString(list)
  235. if !ok {
  236. return nil, nil, false
  237. }
  238. out = append(out, tuple{string(name), string(data)})
  239. }
  240. ok = true
  241. return
  242. }
  243. func signatureLength(sig *signature) int {
  244. length := 4 // length prefix for signature
  245. length += stringLength(len(sig.Format))
  246. length += stringLength(len(sig.Blob))
  247. return length
  248. }
  249. func marshalSignature(to []byte, sig *signature) []byte {
  250. length := uint32(signatureLength(sig) - 4)
  251. to = marshalUint32(to, length)
  252. to = marshalString(to, []byte(sig.Format))
  253. to = marshalString(to, sig.Blob)
  254. return to
  255. }
  256. func parseSignature(in []byte) (out *signature, rest []byte, ok bool) {
  257. var sigBytes, format []byte
  258. sig := new(signature)
  259. if sigBytes, rest, ok = parseString(in); !ok {
  260. return
  261. }
  262. if format, sigBytes, ok = parseString(sigBytes); !ok {
  263. return
  264. }
  265. sig.Format = string(format)
  266. if sig.Blob, sigBytes, ok = parseString(sigBytes); !ok {
  267. return
  268. }
  269. return sig, rest, ok
  270. }