From e6ba498e0028cee028fdb2ba0ede3de34e945777 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 26 Nov 2015 15:33:23 +0100 Subject: [PATCH] add createCerts commandline switch will be used during installation to trigger a new certificate creation --- certificates.go | 156 +++++++++++++++++++++++++++++++++++++++++++++ fakecerts/cert.cer | Bin 776 -> 0 bytes fakecerts/cert.pem | 19 ------ fakecerts/key.pem | 27 -------- main.go | 11 ++++ 5 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 certificates.go delete mode 100644 fakecerts/cert.cer delete mode 100644 fakecerts/cert.pem delete mode 100644 fakecerts/key.pem diff --git a/certificates.go b/certificates.go new file mode 100644 index 000000000..a1451b959 --- /dev/null +++ b/certificates.go @@ -0,0 +1,156 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'cert.pem' and 'key.pem' and will overwrite existing files. + +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + log "github.com/Sirupsen/logrus" + "io/ioutil" + "math/big" + "net" + "os" + "strings" + "time" +) + +var ( + host = "localhost" + validFrom = "" + validFor = 365 * 24 * time.Hour * 2 // 2 years + isCA = true + rsaBits = 2048 + ecdsaCurve = "" +) + +func publicKey(priv interface{}) interface{} { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + default: + return nil + } +} + +func pemBlockForKey(priv interface{}) *pem.Block { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} + case *ecdsa.PrivateKey: + b, err := x509.MarshalECPrivateKey(k) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) + os.Exit(2) + } + return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} + default: + return nil + } +} + +func generateCertificates() { + + var priv interface{} + var err error + switch ecdsaCurve { + case "": + priv, err = rsa.GenerateKey(rand.Reader, rsaBits) + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + default: + fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", ecdsaCurve) + os.Exit(1) + } + if err != nil { + log.Fatalf("failed to generate private key: %s", err) + } + + var notBefore time.Time + if len(validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) + os.Exit(1) + } + } + + notAfter := notBefore.Add(validFor) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Arduino LLC US"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + if isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalf("Failed to create certificate: %s", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("failed to open cert.pem for writing: %s", err) + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + log.Print("written cert.pem\n") + + ioutil.WriteFile("cert.cer", derBytes, 0644) + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Print("failed to open key.pem for writing:", err) + return + } + pem.Encode(keyOut, pemBlockForKey(priv)) + keyOut.Close() + log.Print("written key.pem\n") +} diff --git a/fakecerts/cert.cer b/fakecerts/cert.cer deleted file mode 100644 index 2e62ff04dce1b254151ffeba5ac651eb31842960..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmXqLVrDUDVtm8I$?#Y2tH`NM6XOkd**LY@JlekVGBUEVG8niRavN~6F^96S2{VNT z8;TeRfjC^k+>S*lrI~s83O+v0FeTi=Or9ZzLIwgLCCtK{Ir+(nIT`uIB?fZhyoRO* zW`>3a=0>K*W>G+{8IWrL=QFZ0FgG#sGXQx+34 z8v@S0-0pttw8Ed-@3o6g=$UdVh!va^n5ui;xWFgnjje>fmXn8EPpa@in~i@%tM( zcbZuy8mo8R-zz(x-z>-_Rp-cVvDc25M4#8Pe>i=7sTb2E&GS2cul{b>dg_qS)z>S+ z)y`_Ah8Ih2y2yCg^z+=3+DWVnonLZ2+IhIcFs~t`;!VYV7v?4|t(SW~Y&zVr_}=ac z?d#cR=h@8F30!W*zhSE7^}y%r;+W-4!zS}CV)}5A;aAE8;{^&Ybe6Sdt*rj8mED)f z#LURRh#W$|2nL1_BZI*7S~l<2CJT1g`lf#JER_P<;X4KsXym>zU?KCxzd3j0X*|&U3xxU?f=I7C2nkm4SB_jWWGNr zy?_4J$N3xOp1Cf$8#7_Y`pYM{D~(`eO8G^xsZ^@Rc6MJu;0ZVnk(#9 cJQbXCe}a^LRB<_f)zsS$R{d}|za;zx0GZq=+5i9m diff --git a/fakecerts/cert.pem b/fakecerts/cert.pem deleted file mode 100644 index 7f648b91c..000000000 --- a/fakecerts/cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAewCCQD9LvUUyrKRXzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJV -UzEUMBIGA1UEChMLQXJkdWlubyBMTEMxCzAJBgNVBAsTAklUMRIwEAYDVQQDEwls -b2NhbGhvc3QwHhcNMTUwNjExMDcyNTM2WhcNMTYwNjEwMDcyNTM2WjBEMQswCQYD -VQQGEwJVUzEUMBIGA1UEChMLQXJkdWlubyBMTEMxCzAJBgNVBAsTAklUMRIwEAYD -VQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7 -3UTunwOvcw1hgFDN6bdHxssg/H33faLILjUJIBZwyRCVLc8zcExk7D0YLxnMBaxs -t4DoPfMlAXiJ+GT3fiOaYTKHmGT3Qz85WC6Yngz9A/usDQSSYe9rI4k3oLNA4F+b -6VU5FBj1V3nj79gs3IMEkTMnit+9HZ8PNlJEZSzEuxbrQdIV530H8MvHpUoCkinP -uPur9zGFysIS1euoVybNKmVXcxmy0QHDNfOddH2SBaFD6QriucOIMW6AVHjseL9E -A4IKKum88LLDiKPeu3gr12vNnjydLFGnNg+wlTnXUeeuXgMfNVaTDaIC8NEA+mSQ -M6Ag6CymhWqpe/cqa45hAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBABCXfQZLhYI4 -B0VjgwDDRohTAhsSyaQvFEhGOx2Oo28RhKgY2xRtfjDlm7IzTLga4ApsHqIMf85F -z4bpDDciwPhQDJ6a0ueXJv+xb6RGBnGAbnOiHPfgdd/P2vGfsR7mRaTdXJC4r9PI -C3kzjwTlplaulLbHs5XIXImGvAvRX5sPmkqlBAQs8PVG4I71pKXo1M4kl7uzr96+ -+DKnVz2oACAPCW6zTlT/MlBH4nSeCQfGiE8iWAqODviONOQjFnaTKLw6d1YnbnLp -1gokB8sk1TAM3qjb6giZpe945xISSNUDAVRW+3NIKag+qOURnN+QGi9ac3cPepXb -4Kr4QM+kV+g= ------END CERTIFICATE----- diff --git a/fakecerts/key.pem b/fakecerts/key.pem deleted file mode 100644 index 26c54a281..000000000 --- a/fakecerts/key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAu91E7p8Dr3MNYYBQzem3R8bLIPx9932iyC41CSAWcMkQlS3P -M3BMZOw9GC8ZzAWsbLeA6D3zJQF4ifhk934jmmEyh5hk90M/OVgumJ4M/QP7rA0E -kmHvayOJN6CzQOBfm+lVORQY9Vd54+/YLNyDBJEzJ4rfvR2fDzZSRGUsxLsW60HS -Fed9B/DLx6VKApIpz7j7q/cxhcrCEtXrqFcmzSplV3MZstEBwzXznXR9kgWhQ+kK -4rnDiDFugFR47Hi/RAOCCirpvPCyw4ij3rt4K9drzZ48nSxRpzYPsJU511Hnrl4D -HzVWkw2iAvDRAPpkkDOgIOgspoVqqXv3KmuOYQIDAQABAoIBADzL4df7W/z2ldj8 -5qmMvkSbP/d/3uAuJ3TzBzTZzolXeGdeuNRjvkVW8nqWG5ocJ+3TAQOnsL1EGZdE -7J/vkWQPmoOpPNuMRrSvJf08AOYM2PCYEeexjAK3MFvxRLF1K1vQikT7jQww8ABl -CSeTgU8EEnL0jW2tXWFV6g+6Ul+jwfq5IvbUpMsMOPuUEQy85rm04bCw/vUnhZXk -gFSpAp5mKPI6J/v2fkJTjgxi0wURxHKFdH/dFr69k9G7Vv9L8meiZYwA0QsYcmeJ -EAGpZHQXpTCmmmzWM85vz9vg4qUBwF8ypXcWjuqfjAopXvuenyIkfa9paDriRnNM -A3JmUQECgYEA66fdY8cU1cJw5jmhc10mi6lDz0Xswba4kaYnb2fwr7tlkBFzYYVn -GY6f2fNxdx8ZpOCYzembJ67qCXODw4LLle1slgHzOWHQ4RJd2EDw/i9woPHGsT3a -TIk0tX3wOjtJJEXNzQEiqcDqGqrpY3pnm4lFGR4RSE6vIYfPwyO9y7ECgYEAzBUv -hKy19GSFK8tkYa/WcmNMCGwLJB0pEMuT3heDjSEKYNaTh8YcIpeEY3aCWbMKxWdu -O5TIouyNJHtm4Q0umG08ZGekLTZy22it2UJabROvHVHeSnPki9a12Uc3KgB6mBzb -nnHXQ8hR60o0GTPMudVW12aZh9gy+EcGWQEwibECgYAIdQ3M9ugYg9HpcUgKC93G -RVzZo3jLuvMExyHDLcfFhsQuV3H8nf0FPcke2U3JKKSS9jyFp0yaL/zWOf8QlTEZ -QFwVRhykgo4shaw4hpwfgzRXklW/Jqke9g2eNdbZQCdv1dF8+f10eifsrRWTLGFr -g5GnRRz5q1k9qtIZ/r5hAQKBgCegMXLMaiQC5IylWF9TWgsp1piICf3AH7ogHRzx -adycPrygzVJ+l/Xrf4wkdZjfF8dOluvArthbn+gmgcpO2e5Ev4YrTYht2w1ZHPBj -XtVxDf5eaBACwqyYSwTePArOvv8ME2SHbCnAGo/Z/5WpJiYrE0qNpF/pDbSBbe0Y -OwlxAoGAdPEjpeeCpyUcoJMVnIxM7AtsOqomd0lBrRgRq05FYvGMAygoKzz+OBp+ -VgptcGJp+6t5MY9R3asRaFp3rOcXvX5R4wBMfijlzoezMEFZN/+xpm7LN2E0domO -xyku5Kcn9G/KTxCduepOtjqoNYkKYAcrdkmRfZ9C9xvuB2lKjk8= ------END RSA PRIVATE KEY----- diff --git a/main.go b/main.go index 87a644dbd..49d4efc55 100755 --- a/main.go +++ b/main.go @@ -39,6 +39,7 @@ var ( hostname = flag.String("hostname", "unknown-hostname", "Override the hostname we get from the OS") updateUrl = flag.String("updateUrl", "", "") appName = flag.String("appName", "", "") + genCert = flag.Bool("generateCert", false, "") globalToolsMap = make(map[string]string) tempToolsPath = createToolsDir() port string @@ -77,6 +78,11 @@ func main() { flag.Parse() + if *genCert == true { + generateCertificates() + exit() + } + if *hibernate == false { go func() { @@ -212,6 +218,11 @@ func main() { r.Handle("WSS", "/socket.io/", socketHandler) r.GET("/info", infoHandler) go func() { + // check if certificates exist; if not, use plain http + if _, err := os.Stat(filepath.Join(dest, "cert.pem")); os.IsNotExist(err) { + return + } + start := 8990 end := 9000 i := start