예제 #1
0
func VerifyMedia(b []byte) (AlexandriaMedia, map[string]interface{}, error) {

	var v AlexandriaMedia
	var i interface{}
	var m map[string]interface{}

	if !strings.HasPrefix(string(b), `{ "alexandria-media"`) &&
		!strings.HasPrefix(string(b), `{"alexandria-media"`) &&
		!strings.HasPrefix(string(b), `{"media-data"`) &&
		!strings.HasPrefix(string(b), `{ "media-data"`) {
		return v, nil, ErrWrongPrefix
	}

	if !utility.IsJSON(string(b)) {
		return v, m, ErrNotJSON
	}

	// fmt.Printf("Attempting to verify alexandria-media JSON...")
	err := json.Unmarshal(b, &v)
	if err != nil {
		return v, m, err
	}

	err = json.Unmarshal(b, &i)
	if err != nil {
		return v, m, err
	}

	m = i.(map[string]interface{})
	var signature string

	// check the JSON object root key
	// find the signature string
	for key, val := range m {
		if key == "signature" {
			signature = val.(string)
		} else {
			if key != MEDIA_ROOT_KEY {
				return v, m, errors.New("can't verify media - JSON object root key doesn't match accepted value")
			}
		}
	}

	// fmt.Printf("*** debug: JSON object root matches, printing v:\n%v\n*** /debug ***\n", v)
	err = checkRequiredMediaFields(v, signature)
	if err != nil {
		return v, m, err
	}

	// verify signature was created by this address
	// signature pre-image for media is <torrenthash>-<publisher>-<timestamp>
	val, _ := utility.CheckSignature(v.AlexandriaMedia.Publisher, signature, v.AlexandriaMedia.Torrent+"-"+v.AlexandriaMedia.Publisher+"-"+strconv.FormatInt(v.AlexandriaMedia.Timestamp, 10))
	if val == false {
		return v, m, ErrBadSignature
	}

	// fmt.Println(" -- VERIFIED --")
	return v, m, nil

}
예제 #2
0
func VerifyPublisher(b []byte) (AlexandriaPublisher, error) {

	var v AlexandriaPublisher
	var i interface{}
	var m map[string]interface{}

	if !strings.HasPrefix(string(b), `{ "alexandria-publisher"`) &&
		!strings.HasPrefix(string(b), `{"alexandria-publisher"`) {
		return v, ErrWrongPrefix
	}

	// fmt.Printf("Attempting to verify alexandria-publisher JSON...")

	if !utility.IsJSON(string(b)) {
		return v, ErrNotJSON
	}

	err := json.Unmarshal(b, &v)
	if err != nil {
		return v, err
	}

	errr := json.Unmarshal(b, &i)
	if errr != nil {
		return v, err
	}

	m = i.(map[string]interface{})
	var signature string

	// check the JSON object root key
	// find the signature string
	for key, val := range m {
		if key == "signature" {
			signature = val.(string)
		} else {
			if key != PUBLISHER_ROOT_KEY {
				return v, errors.New("can't verify publisher - JSON object root key doesn't match accepted value")
			}
		}
	}

	// verify signature
	if v.Signature != signature {
		return v, ErrBadSignature
	}

	// verify signature was created by this address
	// signature pre-image for publisher is <name>-<address>-<timestamp>
	val, _ := utility.CheckSignature(v.AlexandriaPublisher.Address, signature, v.AlexandriaPublisher.Name+"-"+v.AlexandriaPublisher.Address+"-"+strconv.FormatInt(v.AlexandriaPublisher.Timestamp, 10))
	if val == false {
		return v, ErrBadSignature
	}

	// fmt.Println(" -- VERIFIED --")
	return v, nil

}
예제 #3
0
func parseV1(s string, block int) (HistorianMessage, error) {
	var hm HistorianMessage

	hm.Version = 1
	parts := strings.Split(s, ":")

	if len(parts) < 6 || len(parts) > 9 {
		return hm, ErrHistorianMessageInvalid
	}
	if len(parts) == 8 {
		hm.Signature = parts[7]
	}
	hm.URL = parts[1]

	p, err := hmPools.GetPool(hm.URL, block, 1)
	if err != nil {
		return hm, err
	}

	// If there's no defined address there is no signature to check
	if p.address != "" {
		i := strings.LastIndex(s, ":")
		val, _ := utility.CheckSignature(p.address, s[i+1:], s[:i])
		if !val {
			return hm, ErrBadSignature
		}
	}

	for i := 2; i < 7; i++ {
		f, err := strconv.ParseFloat(parts[i], 64)
		if err != nil {
			f = math.Inf(-1)
		}
		switch i {
		case 2:
			hm.Mrr_last_10 = f
		case 3:
			hm.Pool_hashrate = f
		case 4:
			hm.Fbd_hashrate = f
		case 5:
			hm.Fmd_weighted = f
		case 6:
			hm.Fmd_usd = f
		}
	}

	return hm, nil
}
예제 #4
0
func VerifyOIP041Transfer(o Oip041) (Oip041, error) {
	oip_t := o.Transfer

	if len(oip_t.Reference) != 64 {
		return o, ErrInvalidReference
	}

	if !utility.CheckAddress(oip_t.To) {
		return o, ErrInvalidAddress
	}

	preImage := oip_t.Reference + "-" + oip_t.To + "-" + oip_t.From + "-" + strconv.FormatInt(oip_t.Timestamp, 10)
	valid, err := utility.CheckSignature(oip_t.From, o.Signature, preImage)
	if !valid {
		return o, err
	}

	return o, nil
}
예제 #5
0
func HandleOIP041Transfer(o Oip041, txid string, processingBlock int, dbtx *sql.Tx) {
	// ToDo: Verify rights to transfer
	// leedle leedle leedle lee

	oip_t := o.Transfer

	if len(oip_t.Reference) != 64 {
		return //oip_t, ErrInvalidReference
	}

	if !utility.CheckAddress(oip_t.To) {
		return //oip_t, ErrInvalidAddress
	}

	preImage := oip_t.Reference + "-" + oip_t.To + "-" + oip_t.From + "-" + strconv.FormatInt(oip_t.Timestamp, 10)
	valid, err := utility.CheckSignature(oip_t.From, o.Signature, preImage)
	if !valid {
		return //oip_t, err
	}

	stmt, err := dbtx.Prepare(`SELECT publisher FROM media WHERE txid = ? LIMIT 1;`)
	if err != nil {
		log.Fatal(err)
	}

	row := stmt.QueryRow(oip_t.Reference)
	var publisher string
	err = row.Scan(&publisher)
	if err != nil {
		log.Fatal(err)
	}
	stmt.Close()

	fmt.Println(publisher)
	if publisher == oip_t.From {
		fmt.Println("Transfered")
		StoreOIPTransfer(oip_t, dbtx)
	} else {
		fmt.Println("Denied")
	}
	fmt.Println()
}
예제 #6
0
func VerifyMediaMultipartSingle(s string, txid string, block int) (MediaMultipartSingle, error) {
	var ret MediaMultipartSingle
	prefix := "alexandria-media-multipart("

	// check prefix
	checkPrefix := strings.HasPrefix(s, prefix)
	if !checkPrefix {
		return ret, ErrWrongPrefix
	}

	// trim prefix off
	s = strings.TrimPrefix(s, prefix)

	// check length
	if len(s) < 108 {
		return ret, errors.New("not enough data in mutlipart string")
	}

	// check part and max
	part, err := strconv.Atoi(string(s[0]))
	if err != nil {
		fmt.Println("cannot convert part to int")
		return ret, errors.New("cannot convert part to int")
	}
	max, err2 := strconv.Atoi(string(s[2]))
	if err2 != nil {
		fmt.Println("cannot convert max to int")
		return ret, errors.New("cannot convert max to int")
	}

	// get and check address
	address := s[4:38]
	if !utility.CheckAddress(address) {
		// fmt.Println("address doesn't check out: \"" + address + "\"")
		return ret, ErrInvalidAddress
	}

	// get reference txid
	reference := s[39:103]

	// get and check signature
	sigEndIndex := strings.Index(s, "):")

	if sigEndIndex < 105 {
		fmt.Println("no end of signature found, malformed tx-comment")
		return ret, ErrNoSignatureEnd
	}

	signature := s[104:sigEndIndex]
	if signature[len(signature)-1] == ',' {
		// strip erroneous comma added by fluffy-enigma
		signature = signature[:len(signature)-1]
	}
	data := s[sigEndIndex+2:]
	// fmt.Println("data: \"" + data + "\"")

	// signature pre-image is <part>-<max>-<address>-<txid>-<data>
	// in the case of multipart[0], txid is 64 zeros
	// in the case of multipart[n], where n != 0, txid is the reference txid (from multipart[0])
	preimage := string(s[0]) + "-" + string(s[2]) + "-" + address + "-" + reference + "-" + data
	// fmt.Printf("preimage: %v\n", preimage)

	val, _ := utility.CheckSignature(address, signature, preimage)
	if !val {
		// fmt.Println("signature didn't pass checksignature test")
		return ret, ErrBadSignature
	}

	// if part == 0, reference should be submitted in the tx-comment as a string of 64 zeros
	// the local DB will store reference = txid for this transaction after it's submitted
	// in case of a reorg, the publisher must re-publish this multipart message (sorry)
	if part == 0 {
		if reference != "0000000000000000000000000000000000000000000000000000000000000000" {
			// fmt.Println("reference txid should be 64 zeros for part 0 of a multipart message")
			return ret, errors.New("reference txid should be 64 zeros for part 0")
		}
		reference = txid
	}
	// all checks passed, verified!

	//fmt.Printf("data: %v\n", data)
	// fmt.Printf("=== VERIFIED ===\n")
	//fmt.Printf("part: %v\nmax: %v\nreference: %v\naddress: %v\nsignature: %v\ntxid: %v\nblock: %v\n", part, max, reference, address, signature, txid, block)

	ret = MediaMultipartSingle{
		Part:      part,
		Max:       max,
		Reference: reference,
		Address:   address,
		Signature: signature,
		Data:      data,
		Txid:      txid,
		Block:     block,
	}

	return ret, nil

}
예제 #7
0
func VerifyDeactivation(b []byte) (AlexandriaDeactivation, error) {

	var v AlexandriaDeactivation
	var i interface{}
	var m map[string]interface{}

	if !strings.HasPrefix(string(b), `{"alexandria-deactivation"`) {
		return v, errors.New("Not alexandria-deactivation")
	}

	if !utility.IsJSON(string(b)) {
		return v, ErrNotJSON
	}

	err := json.Unmarshal(b, &v)
	if err != nil {
		return v, err
	}

	errr := json.Unmarshal(b, &i)
	if errr != nil {
		return v, err
	}

	m = i.(map[string]interface{})
	var signature string

	// check the JSON object root key
	// find the signature string
	for key, val := range m {
		if key == "signature" {
			signature = val.(string)
		} else {
			if key != DEACTIVATION_ROOT_KEY {
				return v, errors.New("can't verify deactivation - JSON object root key doesn't match accepted value")
			}
		}
	}

	// verify txid
	rt := regexp.MustCompile("^[a-fA-F0-9]*$")
	if !rt.MatchString(v.AlexandriaDeactivation.Txid) || len(v.AlexandriaDeactivation.Txid) != 64 {
		return v, errors.New("can't verify deactivation - txid in incorrect format")
	}

	// verify address
	ra := regexp.MustCompile("^[a-zA-Z0-9]*$")
	if !ra.MatchString(v.AlexandriaDeactivation.Address) || len(v.AlexandriaDeactivation.Address) != 34 {
		return v, errors.New("can't verify deactivation - address in incorrect format")
	}

	// verify signature
	if v.Signature != signature {
		return v, ErrBadSignature
	}

	// verify signature was created by this address
	// signature pre-image for deactivation is <address>-<txid>
	val, _ := utility.CheckSignature(v.AlexandriaDeactivation.Address, signature, v.AlexandriaDeactivation.Address+"-"+v.AlexandriaDeactivation.Txid)
	if val == false {
		return v, ErrBadSignature
	}

	return v, nil

}