예제 #1
0
func TestBasic(t *testing.T) {
	var priv, pub [32]byte
	rand.Read(priv[:])
	curve25519.ScalarBaseMult(&pub, &priv)

	var d Descriptor
	d.Nickname = "mylittletorry18"
	d.Contact = "TvdW"
	d.Platform = "Tor 0.2.6.2-alpha on MS-DOS"
	d.Address = net.ParseIP("80.57.124.58")
	d.ORPort = 1234
	d.UptimeStart = time.Now()
	d.NTORKey = pub[:]
	d.BandwidthAvg = 1000000
	d.BandwidthBurst = 1200000
	d.BandwidthObserved = 30107
	k, err := openssl.GenerateRSAKeyWithExponent(1024, 65537)
	if err != nil {
		t.Error(err)
	}
	d.OnionKey, err = openssl.GenerateRSAKeyWithExponent(1024, 65537)
	d.SigningKey = k
	desc, err := d.SignedDescriptor()
	if err != nil {
		t.Error(err)
	}

	log.Println(desc)
}
예제 #2
0
파일: tls.go 프로젝트: nemesisqp/gotor
func NewTLSCtx(isClient bool, or *ORCtx) (*TorTLS, error) {
	log.Printf("Creating TLS context with isClient=%v\n", isClient)

	sslCtx, err := openssl.NewCtxWithVersion(openssl.AnyVersion)
	if err != nil {
		return nil, err
	}

	tls := &TorTLS{
		ctx: sslCtx,
	}

	// Considering how important this piece of code is for resisting fingerprints, we just follow whatever Tor itself does

	if !isClient { // XXX simplify
		nickname1 := RandomHostname(8, 20, "www.", ".net")
		nickname2 := RandomHostname(8, 20, "www.", ".com")

		issued, _ := time.ParseDuration("-24h") // XXX check what tor does (some time ago, then a long-time cert)
		expires, _ := time.ParseDuration("24h") // XXX also, don't re-use for all certs

		tmpPk, err := openssl.GenerateRSAKeyWithExponent(1024, 65537)
		if err != nil {
			return nil, err
		}

		authPk, err := openssl.GenerateRSAKeyWithExponent(1024, 65537)
		if err != nil {
			return nil, err
		}

		cert, err := openssl.NewCertificate(&openssl.CertificateInfo{
			CommonName: nickname1,
			Serial:     rand.Int63(),
			Issued:     issued,
			Expires:    expires,
		}, tmpPk)
		if err != nil {
			return nil, err
		}

		identityPk := or.identityKey

		idcert, err := openssl.NewCertificate(&openssl.CertificateInfo{
			CommonName: nickname2,
			Serial:     rand.Int63(),
			Issued:     issued,
			Expires:    expires,
		}, identityPk)
		if err != nil {
			return nil, err
		}

		authcert, err := openssl.NewCertificate(&openssl.CertificateInfo{
			CommonName: nickname1,
			Serial:     rand.Int63(),
			Issued:     issued,
			Expires:    expires,
		}, authPk)
		if err != nil {
			return nil, err
		}

		if err := cert.SetIssuer(idcert); err != nil {
			return nil, err
		}
		if err := cert.Sign(identityPk, openssl.EVP_SHA1); err != nil {
			return nil, err
		}

		if err := idcert.SetIssuer(idcert); err != nil {
			return nil, err
		}
		if err := idcert.Sign(identityPk, openssl.EVP_SHA1); err != nil {
			return nil, err
		}

		if err := authcert.SetIssuer(idcert); err != nil {
			return nil, err
		}
		if err := authcert.Sign(identityPk, openssl.EVP_SHA1); err != nil {
			return nil, err
		}

		sslCtx.UseCertificate(cert)
		sslCtx.UsePrivateKey(tmpPk)

		sslCtx.SetEllipticCurve(openssl.Prime256v1)

		tls.LinkCert = cert
		tls.LinkKey = tmpPk
		tls.LinkCertDER, err = cert.MarshalDER()
		if err != nil {
			return nil, err
		}

		tls.IdCert = idcert
		tls.IdKey = identityPk
		tls.IdCertDER, err = idcert.MarshalDER()
		if err != nil {
			return nil, err
		}

		keyDer, _ := identityPk.MarshalPKCS1PublicKeyDER()
		fingerprint := sha1.Sum(keyDer)
		log.Printf("Our fingerprint is %X\n", fingerprint)
		copy(tls.Fingerprint[:], fingerprint[:])

		{
			sha := sha256.New()
			sha.Write(keyDer)
			tls.Fingerprint256 = sha.Sum(nil)
		}

		tls.AuthCert = authcert
		tls.AuthKey = authPk
		tls.AuthCertDER, err = authcert.MarshalDER()
		if err != nil {
			return nil, err
		}
	}

	// We don't want SSLv2 or SSLv3
	sslCtx.SetOptions(openssl.NoSSLv2 | openssl.NoSSLv3)

	// Prefer the server's ordering of ciphers: the client's ordering has
	// historically been chosen for fingerprinting resistance.
	sslCtx.SetOptions(openssl.CipherServerPreference)

	//XXX: panic() if we don't have openssl of 1.0.1e or later
	//XXX: please remember me why...

	// Tickets hurt perfect forward secrecy, but we still have non-server clients announce them, to reduce fingerprinting impact
	if !isClient {
		sslCtx.SetOptions(openssl.NoTicket)
	}

	// This saves us quite some memory
	//sslCtx.SetMode(openssl.ReleaseBuffers)

	// Avoid reusing DH keys if we don't have to
	sslCtx.SetOptions(openssl.SingleDHUse | openssl.SingleECDHUse)

	// Never renegotiate.
	sslCtx.SetOptions(openssl.NoSessionResumptionOrRenegotiation)

	// All compression does with encrypted data is waste CPU cycles. Disable it
	sslCtx.SetOptions(openssl.NoCompression)

	// Disable session caching
	sslCtx.SetSessionCacheMode(openssl.SessionCacheOff)

	// Allow all peer certificates
	sslCtx.SetVerify(openssl.VerifyNone, nil)

	return tls, nil
}
예제 #3
0
파일: or.go 프로젝트: nemesisqp/gotor
func NewOR(torConf *Config) (*ORCtx, error) {
	connStr := fmt.Sprintf(":%d", torConf.ORPort)
	listener, err := net.Listen("tcp", connStr)
	if err != nil {
		return nil, err
	}

	ctx := &ORCtx{
		listener:                 listener,
		authenticatedConnections: make(map[Fingerprint]*OnionConnection),
		config: torConf,
	}

	if _, err := os.Stat(torConf.DataDirectory + "/keys/secret_id_key"); os.IsNotExist(err) {
		Log(LOG_INFO, "Generating new keys")
		os.Mkdir(torConf.DataDirectory, 0755)
		os.Mkdir(torConf.DataDirectory+"/keys", 0700)

		{
			newIDKey, err := openssl.GenerateRSAKeyWithExponent(1024, 65537)
			if err != nil {
				return nil, err
			}
			newIDKeyPEM, err := newIDKey.MarshalPKCS1PrivateKeyPEM()
			if err != nil {
				return nil, err
			}
			if err := ioutil.WriteFile(torConf.DataDirectory+"/keys/secret_id_key", newIDKeyPEM, 0600); err != nil {
				return nil, err
			}
		}

		{
			newOnionKey, err := openssl.GenerateRSAKeyWithExponent(1024, 65537)
			if err != nil {
				return nil, err
			}
			newOnionKeyPEM, err := newOnionKey.MarshalPKCS1PrivateKeyPEM()
			if err != nil {
				return nil, err
			}
			if err := ioutil.WriteFile(torConf.DataDirectory+"/keys/secret_onion_key", newOnionKeyPEM, 0600); err != nil {
				return nil, err
			}
		}

		{
			var curveDataPriv [32]byte
			var curveDataPub [32]byte
			CRandBytes(curveDataPriv[0:32])
			curveDataPriv[0] &= 248
			curveDataPriv[31] &= 127
			curveDataPriv[31] |= 64
			curve25519.ScalarBaseMult(&curveDataPub, &curveDataPriv)

			var buf bytes.Buffer
			buf.WriteString("== c25519v1: onion ==")
			for i := buf.Len(); i < 32; i++ {
				buf.Write([]byte{0})
			}
			buf.Write(curveDataPriv[:])
			buf.Write(curveDataPub[:])
			if err := ioutil.WriteFile(torConf.DataDirectory+"/keys/secret_onion_key_ntor", buf.Bytes(), 0600); err != nil {
				return nil, err
			}
		}
	}

	{
		identityPem, err := ioutil.ReadFile(torConf.DataDirectory + "/keys/secret_id_key")
		if err != nil {
			return nil, err
		}
		identityPk, err := openssl.LoadPrivateKeyFromPEM(identityPem)
		if err != nil {
			return nil, err
		}
		ctx.identityKey = identityPk
	}
	{
		onionPem, err := ioutil.ReadFile(torConf.DataDirectory + "/keys/secret_onion_key")
		if err != nil {
			return nil, err
		}
		onionPk, err := openssl.LoadPrivateKeyFromPEM(onionPem)
		if err != nil {
			return nil, err
		}
		ctx.onionKey = onionPk
	}
	{
		ntorData, err := ioutil.ReadFile(torConf.DataDirectory + "/keys/secret_onion_key_ntor")
		if err != nil {
			return nil, err
		}
		if len(ntorData) != 96 {
			return nil, errors.New("ntor data corrupt")
		}
		copy(ctx.ntorPrivate[:], ntorData[32:64])
		copy(ctx.ntorPublic[:], ntorData[64:96])
	}

	if err := SetupTLS(ctx); err != nil {
		return nil, err
	}

	ctx.descriptor.UptimeStart = time.Now()

	return ctx, nil
}