Example #1
0
// Runs this Hash's text child through a base64 decoder and replaces it with
// the result. Garbage characters (such as whitespace) are ignored during the
// decoding.
func (self *Hash) DecodeBase64() {
	text := self.TextFragments()
	self.SetText()
	var carry int
	for i := range text {
		self.AppendString(string(util.Base64DecodeString(text[i], &carry)))
	}
	flush := string(util.Base64DecodeString("=", &carry))
	self.AppendString(flush)
}
Example #2
0
func (e *base64Eater) Eat(b byte) int {
	if b <= ' ' || e.status != 0 { // ignore control characters; also exit if we have a status
		return e.status
	}
	carry_old := e.carry
	decoded := util.Base64DecodeString(string([]byte{b}), &e.carry)
	if len(decoded) == 0 {
		if carry_old == e.carry { // no result and no state change => garbage
			e.status = -1
		}
	} else {
		for _, dec := range decoded {
			e.status = e.daisy.Eat(dec)
		}
	}

	return e.status
}
Example #3
0
// Tries to decrypt msg with the given key and returns the decrypted message or
// the empty string if decryption failed. Decryption will be considered successful
// if the decrypted message starts with "<xml>" (after trimming whitespace).
//
// Whitespace will be trimmed at the start and end of msg before decryption.
//
// msg can be one of the following:
//
// * an unencrypted message starting (after trimming) with "<xml>". It will be
// returned trimmed but otherwise unchanged.
//
// * a base64 string as returned by GosaEncrypt when used with the same key.
// The unencrypted message will be returned.
//
// The key is a word as used in gosa-si.conf whose md5sum will
// be used as the actual AES key.
func GosaDecrypt(msg string, key string) string {
	trimmed := strings.TrimSpace(msg)

	if strings.HasPrefix(trimmed, "<xml>") {
		return trimmed
	}

	// Fixes the following:
	// * gosa-si bug in the following line:
	//     if( $client_answer =~ s/session_id=(\d+)$// ) {
	//   This leaves the "." before "session_id" which breaks base64
	// * new gosa-si protocol has ";IP:PORT" appended to message
	//   which also breaks base64
	semicolon_period := strings.IndexAny(trimmed, ";.")
	if semicolon_period >= 0 {
		trimmed = trimmed[:semicolon_period]
	}

	cyphertext := util.Base64DecodeString(trimmed, nil)

	if len(cyphertext)%aes.BlockSize != 0 {
		return ""
	}

	aes, _ := aes.NewCipher([]byte(util.Md5sum(key)))
	crypter := cipher.NewCBCDecrypter(aes, config.InitializationVector)
	crypter.CryptBlocks(cyphertext, cyphertext)

	for len(cyphertext) > 0 && cyphertext[0] == 0 {
		cyphertext = cyphertext[1:]
	}
	for len(cyphertext) > 0 && cyphertext[len(cyphertext)-1] == 0 {
		cyphertext = cyphertext[:len(cyphertext)-1]
	}
	trimmed = strings.TrimSpace(string(cyphertext))
	if strings.HasPrefix(trimmed, "<xml>") {
		return trimmed
	}

	return ""
}
Example #4
0
func testBase64() {
	check(util.Base64DecodeString("", nil), []byte{})
	check(util.Base64DecodeInPlace([]byte{}), []byte{})
	check(util.Base64DecodeString("=", nil), []byte{})
	check(util.Base64DecodeInPlace([]byte("=")), []byte{})
	check(util.Base64DecodeString("  =  ", nil), []byte{})
	check(util.Base64DecodeInPlace([]byte("  =  ")), []byte{})
	check(util.Base64DecodeString("/+/+", nil), []byte{0xff, 0xef, 0xfe})
	check(util.Base64DecodeInPlace([]byte("/+/+")), []byte{0xff, 0xef, 0xfe})
	check(util.Base64DecodeString("_-_-", nil), []byte{0xff, 0xef, 0xfe})
	check(util.Base64DecodeInPlace([]byte("_-_-")), []byte{0xff, 0xef, 0xfe})
	var devnull int
	check(string(util.Base64DecodeString("SGFsbG8=", nil)), "Hallo")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbG8="))), "Hallo")
	check(string(util.Base64DecodeString("SGFsbA==", nil)), "Hall")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbA=="))), "Hall")
	check(string(util.Base64DecodeString("SGFsbG8", nil)), "Hallo")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbG8"))), "Hallo")
	check(string(util.Base64DecodeString("SGFsbA=", nil)), "Hall")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbA="))), "Hall")
	check(string(util.Base64DecodeString("SGFsbG8===", nil)), "Hallo")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbG8==="))), "Hallo")
	check(string(util.Base64DecodeString("SGFsbA", nil)), "Hall")
	check(string(util.Base64DecodeInPlace([]byte("SGFsbA"))), "Hall")
	check(string(util.Base64DecodeString("SGFsbG8=", &devnull)), "Hallo")
	check(devnull, 0)
	check(string(util.Base64DecodeString("SGFsbA==", &devnull)), "Hall")
	check(devnull, 0)
	check(string(util.Base64DecodeString("SGFsbA=", &devnull)), "Hall")
	check(devnull, 0)
	check(string(util.Base64DecodeString("SGFsbG8===", &devnull)), "Hallo")
	check(devnull, 0)
	check(string(util.Base64DecodeString("AA", nil)), "\000")
	check(string(util.Base64DecodeInPlace([]byte("AA"))), "\000")
	check(string(util.Base64DecodeString("AAA", nil)), "\000\000")
	check(string(util.Base64DecodeInPlace([]byte("AAA"))), "\000\000")
	var zerocarry int
	check(string(util.Base64DecodeString("AA", &zerocarry)), "")
	check(zerocarry != 0, true)
	check(string(util.Base64DecodeString("=", &zerocarry)), "\000")
	check(zerocarry, 0)
	check(string(util.Base64DecodeString("AAA", &zerocarry)), "")
	check(zerocarry != 0, true)
	check(string(util.Base64DecodeString("=", &zerocarry)), "\000\000")
	check(zerocarry, 0)

	testbuf := make([]byte, 1024)
	for i := range testbuf {
		testbuf[i] = byte(i)
	}

	error_list := ""
	for length := 0; length <= 12; length++ {
		for eq := 0; eq <= 4; eq++ {
			for err := 0; err <= 12; err++ {
				b64_1 := base64.StdEncoding.EncodeToString(testbuf[0 : 512-length])

				testslice := b64_1[0:]
				errors := []int{0}
				for e := 0; e < err; e++ {
					errors = append(errors, errors[e]+rand.Intn(len(testslice)-errors[e]))
				}
				errors = append(errors, len(testslice))
				teststr := ""
				for i := 0; i < len(errors)-1; i++ {
					if i != 0 {
						teststr = teststr + "\000\n"
					}
					teststr = teststr + testslice[errors[i]:errors[i+1]]
				}

				for i := 0; i < eq; i++ {
					teststr += "="
				}
				// because we're concatenating we need at least 1 "=" if the
				// first string ends in an incomplete block
				if eq == 0 && (length&3) != 0 {
					teststr += "="
				}

				b64_2 := base64.URLEncoding.EncodeToString(testbuf[512-length:])

				testslice = b64_2[0:]
				errors = []int{0}
				for e := 0; e < err; e++ {
					errors = append(errors, errors[e]+rand.Intn(len(testslice)-errors[e]))
				}
				errors = append(errors, len(testslice))
				for i := 0; i < len(errors)-1; i++ {
					if i != 0 {
						teststr = teststr + " "
					}
					teststr = teststr + testslice[errors[i]:errors[i+1]]
				}

				for i := 0; i < eq; i++ {
					teststr += "="
				}

				for parts := 0; parts < 5; parts++ {
					stops := []int{0}
					for e := 0; e < parts; e++ {
						stops = append(stops, stops[e]+rand.Intn(len(teststr)-stops[e]))
					}
					stops = append(stops, len(teststr))

					decoded := ""
					carry := 0
					for i := 0; i < len(stops)-1; i++ {
						decoded += string(util.Base64DecodeString(teststr[stops[i]:stops[i+1]], &carry))
					}

					if decoded != string(testbuf) {
						error_list += fmt.Sprintf("(util.Base64DecodeString() failed for length=%v eq=%v err=%v parts=%v)\n", length, eq, err, parts)
					}

					buffy := []byte(string(teststr))
					decbuffy := util.Base64DecodeInPlace(buffy)
					if &(decbuffy[0]) != &(buffy[0]) || // verify the in-place property
						string(decbuffy) != string(testbuf) {
						error_list += fmt.Sprintf("(util.Base64DecodeInPlace() failed for length=%v eq=%v err=%v parts=%v)\n", length, eq, err, parts)
					}
				}
			}
		}
	}

	check(error_list, "")

	buffy := make([]byte, 1024)
	st := "Nehmt, esst. Dies ist mein Leib - sprach der Schokohase"
	copy(buffy[32:], st)
	result := util.Base64EncodeInPlace(buffy[:32+len(st)], 32)
	check(&(buffy[0]) == &(result[0]), true)
	check(cap(result), cap(buffy))
	check(string(result), "TmVobXQsIGVzc3QuIERpZXMgaXN0IG1laW4gTGVpYiAtIHNwcmFjaCBkZXIgU2Nob2tvaGFzZQ==")

	st = "Nehmt, esst. Dies ist mein Leib - sprach der Schokohase\n"
	copy(buffy[256:], st)
	result = util.Base64EncodeInPlace(buffy[:256+len(st)], 256)
	check(&(buffy[0]) == &(result[0]), true)
	check(cap(result), cap(buffy))
	check(string(result), "TmVobXQsIGVzc3QuIERpZXMgaXN0IG1laW4gTGVpYiAtIHNwcmFjaCBkZXIgU2Nob2tvaGFzZQo=")

	for n := 0; n <= 12; n++ {
		buffy = make([]byte, n)
		for i := range buffy {
			buffy[i] = byte(i)
		}
		check(string(util.Base64EncodeString(string(buffy))), base64.StdEncoding.EncodeToString(buffy))
	}
}