I'm having a hard time unmarshalling a struct that is sent to me from an AWS lambda function.
All of the pkidata
fields are empty no matter what I do. I created this code sample to isolate the process :
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
)
func main() {
mystring := `{"error":{"errormessage": "errormessagetest", "errortype": "errortypetest"}, "pkidata":{"certificate":"Q2VydGlmaWNhdGU6CiAgICBEYXRhOgogICAgICAgIFZlcnNpb246IDMgKDB4MikKICAgICAgICBTZXJpYWwgTnVtYmVyOgogICAgICAgICAgICBhYTo5MzpiMTo4MDphYjpiYTplYzo5ZTo4MzpmOTo2OTo5NToyNDpkZjo5Njo2OQogICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KICAgICAgICBJc3N1ZXI6IENOPXJhcGhvZXN0ZXIKICAgICAgICBWYWxpZGl0eQogICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjcgMTk6NDM6MTQgMjAyMiBHTVQKICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDI5IDE5OjQzOjE0IDIwMjQgR01UCiAgICAgICAgU3ViamVjdDogQ049cmFwaG9lc3RlcgogICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgogICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgogICAgICAgICAgICAgICAgUHVibGljLUtleTogKDIwNDggYml0KQogICAgICAgICAgICAgICAgTW9kdWx1czoKICAgICAgICAgICAgICAgICAgICAwMDpjNjplZjpkNjoxYTo0Mjo0Mjo2ZTo5MTpiODpmNTpiZjoyNToyNTpkODoKICAgICAgICAgICAgICAgICAgICBhNjo4Yjo4MzpmYjo2ZDo4MzpiNjowZTo3Mzo4ZjowYTozMjo5ZjpjNjplMjoKICAgICAgICAgICAgICAgICAgICBmMTo4Njo5NDoxMzo5MjplYjo0MTozNTo4NTpiZDo0ZDpkNzowNzo4ZTo5YjoKICAgICAgICAgICAgICAgICAgICBjYzoyYzpkMjo2Nzo5ZDpjOTo1Mzo4Yjo4ODpjZToxMTozOTpkODpkZTo3MjoKICAgICAgICAgICAgICAgICAgICBhMTphODo4MDozMDpmOTpiYTpiOTo3NTpjNTphMjoxYjpiZToyMDo3Yzo1ZjoKICAgICAgICAgICAgICAgICAgICBhMjpjZjpiNzphMjo2ODo4MzpiMzoxMTplODoyNTo3Mzo2MzoyNjphNzpiODoKICAgICAgICAgICAgICAgICAgICBjMzpjZDpjODplZTozNjphZjo4ZTo4ZjowZTo5NDowMToyMDpmZjowZTo0MToKICAgICAgICAgICAgICAgICAgICBjYjplZDpmYjo3NDowNToyZDo0NDphOToxNjoxZDo0ODpkNDphNDo3NTo0ZjoKICAgICAgICAgICAgICAgICAgICBlZjo0NDozYTphMDpmMDo1ZTo5ZTo5YjoxOTphZTo4MTozMzpkMDpkMTpmYzoKICAgICAgICAgICAgICAgICAgICA0MTphMTo1OTo5Zjo3MDoxZDphYTo3MzoyNTpiNTpiNjo3NDo2Mzo1NzpjZjoKICAgICAgICAgICAgICAgICAgICAzNTplNzpiZToyNjo1MzoxNDpkNTplNzpiMzpmYToyZDpjYzo5NToyMzo0ODoKICAgICAgICAgICAgICAgICAgICBkOTpkNTozNDplMjowNzoxYjoyNzoyMzpiZTpiODpmNzpiNTpkOTo3MDo1ZDoKICAgICAgICAgICAgICAgICAgICAyOTo4NTo3NToyYjpmYTo0MjpmNTo2Mjo1OTozZjowODo3Njo0Nzo2NjpmNzoKICAgICAgICAgICAgICAgICAgICAxYzpiYzozNzo1MjpiMDo3ODoyNzozNDo3MTo3ZTpiNjozZDowNDpjZDoyMzoKICAgICAgICAgICAgICAgICAgICAzMjphNjoxYTo2NzphNDo4ODoyYTowYTpmMjoxMjphNTo3ODpkYjpiZDpjOToKICAgICAgICAgICAgICAgICAgICA1ZToxMTo4Njo0MDpkMTo0MTplZjpkYzo2Yjo4Zjo1NjpmZDo1MjpkYTo0ZjoKICAgICAgICAgICAgICAgICAgICBiNTpmMDozYTpmZTpjNzoxMDo3ZTpjNDo3OTo2MTo1ZTpkYjo5Zjo4NjpjOToKICAgICAgICAgICAgICAgICAgICBmYjpiNwogICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQogICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgogICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAogICAgICAgICAgICAgICAgQ0E6RkFMU0UKICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAogICAgICAgICAgICAgICAgMDU6M0Y6RDk6MjE6Rjg6MUE6QjM6NDM6OEQ6QzI6NDA6NzI6OUY6MDE6NDg6MTc6NDE6Nzc6Q0U6MzkKICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCiAgICAgICAgICAgICAgICBrZXlpZDozNTpCRjpBOTozRDo1RjozMzozODowQjowNjo3QzpDQTpFQzo0ODo3QzpCRTo3Njo3MzpCRTpEQjpGRQogICAgICAgICAgICAgICAgRGlyTmFtZTovQ049cmFwaG9lc3RlcgogICAgICAgICAgICAgICAgc2VyaWFsOjhGOjE3OkY1OjJBOjhBOkI0OkQwOjY5CgogICAgICAgICAgICBYNTA5djMgRXh0ZW5kZWQgS2V5IFVzYWdlOiAKICAgICAgICAgICAgICAgIFRMUyBXZWIgU2VydmVyIEF1dGhlbnRpY2F0aW9uCiAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAogICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIEtleSBFbmNpcGhlcm1lbnQKICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZTogCiAgICAgICAgICAgICAgICBETlM6cmFwaG9lc3RlcgogICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KICAgICAgICAgNTg6M2U6MTE6ZmQ6OWM6ZWQ6MTA6YmQ6NmM6NWE6OWY6NzY6OGY6OTc6MGE6YTY6Mzg6ODI6CiAgICAgICAgIDFhOmYwOmJlOjRiOmU4OjEwOmQ4OjNlOmFhOmFlOjIwOmNiOmMzOjI2OjY1OmU3OmI3OmM3OgogICAgICAgICBjNzo2MToxZTpjNjplMjpjYTpmODo1NTo4ZTpkODoxNjozODphZjo3ZjphZDo3Mjo1MzoxYzoKICAgICAgICAgNmE6MzI6NjE6M2U6ZDM6M2E6NWI6NTg6OTU6NDU6ZGE6MGQ6ZTg6ZjQ6NDM6ZWY6NmY6ZmM6CiAgICAgICAgIDE4OmQxOjA4OjA5OjZlOmQ5OjRmOmQ3OjljOmU2OjliOjAzOmU3OjczOjhkOjExOjNhOjkyOgogICAgICAgICBiMDozYTpjOTpiNDo2MjpmNDphODpiMTphMDo0MzpkMzplODoyZjphZDo5Yjo4ZjoyZjpjZjoKICAgICAgICAgZTA6ZTY6YzE6MWM6MDc6N2E6OWY6YjM6NTI6NWU6MzM6ZWU6MjE6NjY6YTU6MDE6YjA6MzQ6CiAgICAgICAgIDUzOjY5OmRjOjIwOmYyOmY4OmJjOjEyOjJiOjNkOjkyOjM3OjdhOjY3OjZiOmJkOjkzOmZlOgogICAgICAgICA1NTpiMTo5YTo4Yjo5NTpiOTpjMDpkYzpiOToxMTo1MDo5ODoyNjo0MzpkOTpkZTo5ZTo2NzoKICAgICAgICAgZTE6NWE6MmI6YTI6ZmU6YWY6ZDE6ODY6NTQ6N2Y6YzE6NjE6Y2E6ZWQ6NjY6N2Y6YWY6ODQ6CiAgICAgICAgIGFiOjAyOmY5OjBhOmUyOmJkOjFhOjQ1OjgzOmU3OjM1Ojc4OjNkOjAzOmRkOjY4OjkyOjhlOgogICAgICAgICA2YTpkODpjZDoyYToxMzplYzphOTowMjo5OTo1Yzo3ZDplZDowMzo2Mzo5Mzo2MDo1ZTpiYToKICAgICAgICAgNDg6ODM6Zjc6ODA6YzA6YzQ6ZDU6YjM6NjI6NGE6MmM6Njc6NTE6YzA6MmM6MDE6NmU6OWM6CiAgICAgICAgIDNkOmExOjQ2OjcwOjZmOmUwOjIxOmYxOjE5OjE1OjJiOmZmOjQwOjNmOjk4OjdlOjMwOjI3OgogICAgICAgICAxYzplZTo5ZDo3ZQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFl6Q0NBa3VnQXdJQkFnSVJBS3FUc1lDcnV1eWVnL2xwbFNUZmxta3dEUVlKS29aSWh2Y05BUUVMQlFBdwpGVEVUTUJFR0ExVUVBd3dLY21Gd2FHOWxjM1JsY2pBZUZ3MHlNakF6TWpjeE9UUXpNVFJhRncweU5EQTJNamt4Ck9UUXpNVFJhTUJVeEV6QVJCZ05WQkFNTUNuSmhjR2h2WlhOMFpYSXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUEKQTRJQkR3QXdnZ0VLQW9JQkFRREc3OVlhUWtKdWtiajF2eVVsMkthTGcvdHRnN1lPYzQ4S01wL0c0dkdHbEJPUwo2MEUxaGIxTjF3ZU9tOHdzMG1lZHlWT0xpTTRST2RqZWNxR29nREQ1dXJsMXhhSWJ2aUI4WDZMUHQ2Sm9nN01SCjZDVnpZeWFudU1QTnlPNDJyNDZQRHBRQklQOE9RY3Z0KzNRRkxVU3BGaDFJMUtSMVQrOUVPcUR3WHA2YkdhNkIKTTlEUi9FR2hXWjl3SGFwekpiVzJkR05YenpYbnZpWlRGTlhucy9vdHpKVWpTTm5WTk9JSEd5Y2p2cmozdGRsdwpYU21GZFN2NlF2VmlXVDhJZGtkbTl4eThOMUt3ZUNjMGNYNjJQUVROSXpLbUdtZWtpQ29LOGhLbGVOdTl5VjRSCmhrRFJRZS9jYTQ5Vy9WTGFUN1h3T3Y3SEVIN0VlV0ZlMjUrR3lmdTNBZ01CQUFHamdhMHdnYW93Q1FZRFZSMFQKQkFJd0FEQWRCZ05WSFE0RUZnUVVCVC9aSWZnYXMwT053a0J5bndGSUYwRjN6amt3UlFZRFZSMGpCRDR3UElBVQpOYitwUFY4ek9Bc0dmTXJzU0h5K2RuTysyLzZoR2FRWE1CVXhFekFSQmdOVkJBTU1DbkpoY0dodlpYTjBaWEtDCkNRQ1BGL1VxaXJUUWFUQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBVEFMQmdOVkhROEVCQU1DQmFBd0ZRWUQKVlIwUkJBNHdESUlLY21Gd2FHOWxjM1JsY2pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVdENFIvWnp0RUwxcwpXcDkyajVjS3BqaUNHdkMrUytnUTJENnFyaURMd3labDU3Zkh4MkVleHVMSytGV08yQlk0cjMrdGNsTWNhakpoClB0TTZXMWlWUmRvTjZQUkQ3Mi84R05FSUNXN1pUOWVjNXBzRDUzT05FVHFTc0RySnRHTDBxTEdnUTlQb0w2MmIKankvUDRPYkJIQWQ2bjdOU1hqUHVJV2FsQWJBMFUybmNJUEw0dkJJclBaSTNlbWRydlpQK1ZiR2FpNVc1d055NQpFVkNZSmtQWjNwNW40Vm9yb3Y2djBZWlVmOEZoeXUxbWY2K0Vxd0w1Q3VLOUdrV0Q1elY0UFFQZGFKS09hdGpOCktoUHNxUUtaWEgzdEEyT1RZRjY2U0lQM2dNREUxYk5pU2l4blVjQXNBVzZjUGFGR2NHL2dJZkVaRlN2L1FEK1kKZmpBbkhPNmRmZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K","privatekey":"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRREc3OVlhUWtKdWtiajEKdnlVbDJLYUxnL3R0ZzdZT2M0OEtNcC9HNHZHR2xCT1M2MEUxaGIxTjF3ZU9tOHdzMG1lZHlWT0xpTTRST2RqZQpjcUdvZ0RENXVybDF4YUlidmlCOFg2TFB0NkpvZzdNUjZDVnpZeWFudU1QTnlPNDJyNDZQRHBRQklQOE9RY3Z0CiszUUZMVVNwRmgxSTFLUjFUKzlFT3FEd1hwNmJHYTZCTTlEUi9FR2hXWjl3SGFwekpiVzJkR05YenpYbnZpWlQKRk5YbnMvb3R6SlVqU05uVk5PSUhHeWNqdnJqM3RkbHdYU21GZFN2NlF2VmlXVDhJZGtkbTl4eThOMUt3ZUNjMApjWDYyUFFUTkl6S21HbWVraUNvSzhoS2xlTnU5eVY0UmhrRFJRZS9jYTQ5Vy9WTGFUN1h3T3Y3SEVIN0VlV0ZlCjI1K0d5ZnUzQWdNQkFBRUNnZ0VBV0loMzhpdTJ3TnBkUkJDVENhckhRNk96QzJQb2E3b0YySFg3SVZueVB3QTcKVGRFZ3JoOGN4ajJDQVhkWWdFSUxGdTk0SE1yL1dpOHlVcDBWVUpYc05kZGhuZ1ljUk5oeVFLZVhIM1lMOHhOWgphQWkyVWdtNE5FQkg4NWNPWEl2NGw3WFhMRUZ4QVBsTE5sZ0hwQjRuUmxDdks3Qm1tRWJBcHM2b3ZSQis2V3JVCkRBWTc0UDNPTi9EMmxyczVNSzlCdlA1d0FsZml1L0x3MTV4NE1UVEE2MkxHNU1remUxV2d0VGtXdnN0VUNXZUUKYW9zQ21tbVhwUGJvR2ZzRXcvSGpWdnZ6UFNKMDhid0U0Mlk2VUFtMGgzWjdMQ1o5ajJtazBsS2NpdStzYndoKwpGL3VvZHdMc2d3bGErNGFGN3g4ZW9rb0RCeVRjVSt1VUVaZWR3MEVKb1FLQmdRRC92ejhFTkM3Q3pSR2VBWjR0Cjhobkdnd2FjbXRjRmVHTHVWVG5iY3ZIZ2EwbVpabk5jdHdpRVlHMm9CYWtkWFcwTmN5WU1tQWlFZXczNTk2Q3QKakxzY0ViSEhMYmV4OGNHWTZlM3gwRFhPTkVGYlBNUnFUTWtIZytIS2tHbWxES3EzUkNxc2RzYnd3T3EyaEd6dApCNnp2SHNuUXlXeEtnMlE2bXVhckpXaUpYd0tCZ1FESElqVEUrQ2pTWkVvZ0E3dG1zN1NkR0cyY0NjNnB0RWRrCmZPZWFGVzJPWDlia2JjakxXcm9zRmpSVm1nbVRXSFZNcnBmR3p5aVBKTWNtanZxbnQzYklVU2JXK2xKMWdZL0sKSTkyL3Q0K09PRTRUL0xYZ09Hc2lOajh1R3ZTMkt2VnNXOE4yMW8vMkE3TklDcEZlTlFuRnFpcW1vazRzV1FjdAprUCtVc3lBMHFRS0JnRUViUXNPak5UUktXRzNOSTZPMnVuRWE4aGYwSTBFMVFKcEVBQktwMUlHNVRtZEsrWnRrCnpUcEdBaVNBTEdsWlcyWE5KcWFXSGJUOFRyYVFIOHVPeENPRkxhanpMb3lTYXlLdWl2REFmTEllQTNWaXB1NFkKMWlTZm9sK2JIQW4waTVGVVBUamlsQXErVWdKYy9BM3JvazdObTdzWFRBWThKTXYybXpwK3Izb3BBb0dBZit1bApZbkxZSm05dWZxcG5GRTZVMCtZQlk1K1pOc01zcVl6amFzUWhJTGpJWHUxM2M4clFsY21kek8rcS94QndLZFp1CmdiUktKY3BHZEtxY3NtalUwVkh3VldGdzN6TmZuMGJ6Q0ZsdXlybTR6bllraitrdVNVZjN4akppeVROSGZWaGwKZEUzWkpQeXppcS9mT2xsdjhaNml6M0NzTHlqeHgzL0I3MUF5ZkNFQ2dZQk5KckJEdnRSZDRCbmVXQjI5Mk84MQpBU0JpWnNPaHFDMnhSWWg1YnYyVFA2clpQd0h0cGV5MmJEK21iQVpLd003TDRKeHJxK3c0aERTN2EwRlowUm1rCi9yRlpvSjR3MDZWNGM2ZndyZG9WZmRvWE5zNkViQmd1ekxab0YyOFNUc3pOZGhFelJkdFNyWWxlalM1UnVDV2UKbUJ1L0g1d1lBNFFtUU9hRzMranFVZz09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K","certificatechain":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhxZ0F3SUJBZ0lKQUk4WDlTcUt0TkJwTUEwR0NTcUdTSWIzRFFFQkN3VUFNQlV4RXpBUkJnTlYKQkFNTUNuSmhjR2h2WlhOMFpYSXdIaGNOTWpJd016STNNVGswTXpBMVdoY05Nekl3TXpJME1UazBNekExV2pBVgpNUk13RVFZRFZRUUREQXB5WVhCb2IyVnpkR1Z5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCCkNnS0NBUUVBdUlqRXJzc0hHSFR3TmNFbjhVTmlKQjErQ0lzL2Q2aklVaXRjUlFJcEhseVJPYzMxaDNyOGlkV0oKK2pGNkFSSndXQThIcmRKYTVCTFhYK3BMWWtMblQ1V2xBVjZkNi9FT2xoUDlCM2tyNHE2ODB0TFhUM3J3UitOdAo0ZTZ0MnUzbjFIS0tsMGM0U25xRGY2b1NjRzE5SGh5OWcvbmp6eFpLVXhZd21tWDRZZXdsSnZNSXZ0VnA5M2JFClQ1MjdJdk5lcFN4MXBBTmhtLzVTRW1zQ3MwQ2pENmZZOXNrcWUra3piZE1TOFhNZlZQYkVXUzdjcG9lZERpSFEKdTVRQVhjSmxnRUVCTjMvbG5JZEpxQ0xQOEFTV2hWd3puSmNEemc5UEcrTlZ4S1A1MHV0bDdROHdsd0Z0R2d4UAp5REhvamNsbVBtQ291UmdHb2RrMnJBQ0lYME9PTFFJREFRQUJvNEdFTUlHQk1CMEdBMVVkRGdRV0JCUTF2Nms5Clh6TTRDd1o4eXV4SWZMNTJjNzdiL2pCRkJnTlZIU01FUGpBOGdCUTF2Nms5WHpNNEN3Wjh5dXhJZkw1MmM3N2IKL3FFWnBCY3dGVEVUTUJFR0ExVUVBd3dLY21Gd2FHOWxjM1JsY29JSkFJOFg5U3FLdE5CcE1Bd0dBMVVkRXdRRgpNQU1CQWY4d0N3WURWUjBQQkFRREFnRUdNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUN6YXU1QlNnSituZy92Cnd2SHVDTnEyZWg5c1M1M3pmVUlQeTZqTUZrZHprelVZTmI1WjFRK1hjb21GbU9xOVVmaWcxN2dZdUR3WC9nMlMKVklDMVJDdWxwVTNORnNLOEhrSDdjdVFPOGNjSnlWc3JtUndPSFhabmtwTnBoYXI4RFQvSjU5d3FNU09ZZUJQYgpuQU41T0piaUF0NlRBNmRsUXJidkFvWG04dXdHMjFSU1N1VHQ5UElsY3NGallQazhiQWJ0dXdldEVnYjVuNkhoClhhczA1S0dteENmZDZxNHAxYUxITkVpNTVSejg0bEVsVHVNZlA0ZEwyZjIzUnFncmpEQmNDRmEwN1owZHJNdjcKbERYNEovaVpXY08zWXJJWXppcVg5M015UzNSUCtrYXAvV0dIYlZDcWtpZ2lTODZwQkY1NDh3OWxXQ0xJai9kTgozRTI2V24zNgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="}}`
// yeah the string is long lol
var body ResponseBody
if err := json.Unmarshal([]byte(mystring), &body); err != nil {
fmt.Println(fmt.Errorf("failed unmarshaling response | %s", err.Error()))
}
fmt.Println(body.Error.ErrorMessage)
certChain, err := base64.StdEncoding.DecodeString(mystring)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(certChain)
}
type PkiGenerationInput struct {
TeacherUsername string `json:"teacherusername"`
}
type Response struct {
Headers ResponseHeaders `json:"headers"`
Body ResponseBody `json:"body"`
}
type ResponseHeaders struct {
ContentType string `json:"Content-Type"`
}
type ResponseBody struct {
PkiData ParsablePkiData `json:"pkidata"`
Error struct {
ErrorMessage string `json:"errormessage"`
ErrorType string `json:"errortype"`
} `json:"error"`
}
type ParsablePkiData struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"privatekey"`
CertificateChain string `json:"certificatechain"`
}
Here is the output
errormessagetest
illegal base64 data at input byte 0
[]
the fact I can read the errormessagetest
shows that the unmarshalling kinda works, so that's weird.
I checked for any unexported fields but we can clearly see they are all capitalized. I also reduced the string size "just to see" and it didn't change anything.
CodePudding user response:
It appears you are decoding the wrong variable.
In your example you are decoding the mystring
variable which is not base64 instead of the actual base64 data.
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
)
func main() {
mystring := `{"error":{"errormessage": "errormessagetest", "errortype": "errortypetest"}, "pkidata":{"certificate":"Q2VydGlmaWNhdGU6CiAgICBEYXRhOgogICAgICAgIFZlcnNpb246IDMgKDB4MikKICAgICAgICBTZXJpYWwgTnVtYmVyOgogICAgICAgICAgICBhYTo5MzpiMTo4MDphYjpiYTplYzo5ZTo4MzpmOTo2OTo5NToyNDpkZjo5Njo2OQogICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KICAgICAgICBJc3N1ZXI6IENOPXJhcGhvZXN0ZXIKICAgICAgICBWYWxpZGl0eQogICAgICAgICAgICBOb3QgQmVmb3JlOiBNYXIgMjcgMTk6NDM6MTQgMjAyMiBHTVQKICAgICAgICAgICAgTm90IEFmdGVyIDogSnVuIDI5IDE5OjQzOjE0IDIwMjQgR01UCiAgICAgICAgU3ViamVjdDogQ049cmFwaG9lc3RlcgogICAgICAgIFN1YmplY3QgUHVibGljIEtleSBJbmZvOgogICAgICAgICAgICBQdWJsaWMgS2V5IEFsZ29yaXRobTogcnNhRW5jcnlwdGlvbgogICAgICAgICAgICAgICAgUHVibGljLUtleTogKDIwNDggYml0KQogICAgICAgICAgICAgICAgTW9kdWx1czoKICAgICAgICAgICAgICAgICAgICAwMDpjNjplZjpkNjoxYTo0Mjo0Mjo2ZTo5MTpiODpmNTpiZjoyNToyNTpkODoKICAgICAgICAgICAgICAgICAgICBhNjo4Yjo4MzpmYjo2ZDo4MzpiNjowZTo3Mzo4ZjowYTozMjo5ZjpjNjplMjoKICAgICAgICAgICAgICAgICAgICBmMTo4Njo5NDoxMzo5MjplYjo0MTozNTo4NTpiZDo0ZDpkNzowNzo4ZTo5YjoKICAgICAgICAgICAgICAgICAgICBjYzoyYzpkMjo2Nzo5ZDpjOTo1Mzo4Yjo4ODpjZToxMTozOTpkODpkZTo3MjoKICAgICAgICAgICAgICAgICAgICBhMTphODo4MDozMDpmOTpiYTpiOTo3NTpjNTphMjoxYjpiZToyMDo3Yzo1ZjoKICAgICAgICAgICAgICAgICAgICBhMjpjZjpiNzphMjo2ODo4MzpiMzoxMTplODoyNTo3Mzo2MzoyNjphNzpiODoKICAgICAgICAgICAgICAgICAgICBjMzpjZDpjODplZTozNjphZjo4ZTo4ZjowZTo5NDowMToyMDpmZjowZTo0MToKICAgICAgICAgICAgICAgICAgICBjYjplZDpmYjo3NDowNToyZDo0NDphOToxNjoxZDo0ODpkNDphNDo3NTo0ZjoKICAgICAgICAgICAgICAgICAgICBlZjo0NDozYTphMDpmMDo1ZTo5ZTo5YjoxOTphZTo4MTozMzpkMDpkMTpmYzoKICAgICAgICAgICAgICAgICAgICA0MTphMTo1OTo5Zjo3MDoxZDphYTo3MzoyNTpiNTpiNjo3NDo2Mzo1NzpjZjoKICAgICAgICAgICAgICAgICAgICAzNTplNzpiZToyNjo1MzoxNDpkNTplNzpiMzpmYToyZDpjYzo5NToyMzo0ODoKICAgICAgICAgICAgICAgICAgICBkOTpkNTozNDplMjowNzoxYjoyNzoyMzpiZTpiODpmNzpiNTpkOTo3MDo1ZDoKICAgICAgICAgICAgICAgICAgICAyOTo4NTo3NToyYjpmYTo0MjpmNTo2Mjo1OTozZjowODo3Njo0Nzo2NjpmNzoKICAgICAgICAgICAgICAgICAgICAxYzpiYzozNzo1MjpiMDo3ODoyNzozNDo3MTo3ZTpiNjozZDowNDpjZDoyMzoKICAgICAgICAgICAgICAgICAgICAzMjphNjoxYTo2NzphNDo4ODoyYTowYTpmMjoxMjphNTo3ODpkYjpiZDpjOToKICAgICAgICAgICAgICAgICAgICA1ZToxMTo4Njo0MDpkMTo0MTplZjpkYzo2Yjo4Zjo1NjpmZDo1MjpkYTo0ZjoKICAgICAgICAgICAgICAgICAgICBiNTpmMDozYTpmZTpjNzoxMDo3ZTpjNDo3OTo2MTo1ZTpkYjo5Zjo4NjpjOToKICAgICAgICAgICAgICAgICAgICBmYjpiNwogICAgICAgICAgICAgICAgRXhwb25lbnQ6IDY1NTM3ICgweDEwMDAxKQogICAgICAgIFg1MDl2MyBleHRlbnNpb25zOgogICAgICAgICAgICBYNTA5djMgQmFzaWMgQ29uc3RyYWludHM6IAogICAgICAgICAgICAgICAgQ0E6RkFMU0UKICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgS2V5IElkZW50aWZpZXI6IAogICAgICAgICAgICAgICAgMDU6M0Y6RDk6MjE6Rjg6MUE6QjM6NDM6OEQ6QzI6NDA6NzI6OUY6MDE6NDg6MTc6NDE6Nzc6Q0U6MzkKICAgICAgICAgICAgWDUwOXYzIEF1dGhvcml0eSBLZXkgSWRlbnRpZmllcjogCiAgICAgICAgICAgICAgICBrZXlpZDozNTpCRjpBOTozRDo1RjozMzozODowQjowNjo3QzpDQTpFQzo0ODo3QzpCRTo3Njo3MzpCRTpEQjpGRQogICAgICAgICAgICAgICAgRGlyTmFtZTovQ049cmFwaG9lc3RlcgogICAgICAgICAgICAgICAgc2VyaWFsOjhGOjE3OkY1OjJBOjhBOkI0OkQwOjY5CgogICAgICAgICAgICBYNTA5djMgRXh0ZW5kZWQgS2V5IFVzYWdlOiAKICAgICAgICAgICAgICAgIFRMUyBXZWIgU2VydmVyIEF1dGhlbnRpY2F0aW9uCiAgICAgICAgICAgIFg1MDl2MyBLZXkgVXNhZ2U6IAogICAgICAgICAgICAgICAgRGlnaXRhbCBTaWduYXR1cmUsIEtleSBFbmNpcGhlcm1lbnQKICAgICAgICAgICAgWDUwOXYzIFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZTogCiAgICAgICAgICAgICAgICBETlM6cmFwaG9lc3RlcgogICAgU2lnbmF0dXJlIEFsZ29yaXRobTogc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24KICAgICAgICAgNTg6M2U6MTE6ZmQ6OWM6ZWQ6MTA6YmQ6NmM6NWE6OWY6NzY6OGY6OTc6MGE6YTY6Mzg6ODI6CiAgICAgICAgIDFhOmYwOmJlOjRiOmU4OjEwOmQ4OjNlOmFhOmFlOjIwOmNiOmMzOjI2OjY1OmU3OmI3OmM3OgogICAgICAgICBjNzo2MToxZTpjNjplMjpjYTpmODo1NTo4ZTpkODoxNjozODphZjo3ZjphZDo3Mjo1MzoxYzoKICAgICAgICAgNmE6MzI6NjE6M2U6ZDM6M2E6NWI6NTg6OTU6NDU6ZGE6MGQ6ZTg6ZjQ6NDM6ZWY6NmY6ZmM6CiAgICAgICAgIDE4OmQxOjA4OjA5OjZlOmQ5OjRmOmQ3OjljOmU2OjliOjAzOmU3OjczOjhkOjExOjNhOjkyOgogICAgICAgICBiMDozYTpjOTpiNDo2MjpmNDphODpiMTphMDo0MzpkMzplODoyZjphZDo5Yjo4ZjoyZjpjZjoKICAgICAgICAgZTA6ZTY6YzE6MWM6MDc6N2E6OWY6YjM6NTI6NWU6MzM6ZWU6MjE6NjY6YTU6MDE6YjA6MzQ6CiAgICAgICAgIDUzOjY5OmRjOjIwOmYyOmY4OmJjOjEyOjJiOjNkOjkyOjM3OjdhOjY3OjZiOmJkOjkzOmZlOgogICAgICAgICA1NTpiMTo5YTo4Yjo5NTpiOTpjMDpkYzpiOToxMTo1MDo5ODoyNjo0MzpkOTpkZTo5ZTo2NzoKICAgICAgICAgZTE6NWE6MmI6YTI6ZmU6YWY6ZDE6ODY6NTQ6N2Y6YzE6NjE6Y2E6ZWQ6NjY6N2Y6YWY6ODQ6CiAgICAgICAgIGFiOjAyOmY5OjBhOmUyOmJkOjFhOjQ1OjgzOmU3OjM1Ojc4OjNkOjAzOmRkOjY4OjkyOjhlOgogICAgICAgICA2YTpkODpjZDoyYToxMzplYzphOTowMjo5OTo1Yzo3ZDplZDowMzo2Mzo5Mzo2MDo1ZTpiYToKICAgICAgICAgNDg6ODM6Zjc6ODA6YzA6YzQ6ZDU6YjM6NjI6NGE6MmM6Njc6NTE6YzA6MmM6MDE6NmU6OWM6CiAgICAgICAgIDNkOmExOjQ2OjcwOjZmOmUwOjIxOmYxOjE5OjE1OjJiOmZmOjQwOjNmOjk4OjdlOjMwOjI3OgogICAgICAgICAxYzplZTo5ZDo3ZQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRFl6Q0NBa3VnQXdJQkFnSVJBS3FUc1lDcnV1eWVnL2xwbFNUZmxta3dEUVlKS29aSWh2Y05BUUVMQlFBdwpGVEVUTUJFR0ExVUVBd3dLY21Gd2FHOWxjM1JsY2pBZUZ3MHlNakF6TWpjeE9UUXpNVFJhRncweU5EQTJNamt4Ck9UUXpNVFJhTUJVeEV6QVJCZ05WQkFNTUNuSmhjR2h2WlhOMFpYSXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUEKQTRJQkR3QXdnZ0VLQW9JQkFRREc3OVlhUWtKdWtiajF2eVVsMkthTGcvdHRnN1lPYzQ4S01wL0c0dkdHbEJPUwo2MEUxaGIxTjF3ZU9tOHdzMG1lZHlWT0xpTTRST2RqZWNxR29nREQ1dXJsMXhhSWJ2aUI4WDZMUHQ2Sm9nN01SCjZDVnpZeWFudU1QTnlPNDJyNDZQRHBRQklQOE9RY3Z0KzNRRkxVU3BGaDFJMUtSMVQrOUVPcUR3WHA2YkdhNkIKTTlEUi9FR2hXWjl3SGFwekpiVzJkR05YenpYbnZpWlRGTlhucy9vdHpKVWpTTm5WTk9JSEd5Y2p2cmozdGRsdwpYU21GZFN2NlF2VmlXVDhJZGtkbTl4eThOMUt3ZUNjMGNYNjJQUVROSXpLbUdtZWtpQ29LOGhLbGVOdTl5VjRSCmhrRFJRZS9jYTQ5Vy9WTGFUN1h3T3Y3SEVIN0VlV0ZlMjUrR3lmdTNBZ01CQUFHamdhMHdnYW93Q1FZRFZSMFQKQkFJd0FEQWRCZ05WSFE0RUZnUVVCVC9aSWZnYXMwT053a0J5bndGSUYwRjN6amt3UlFZRFZSMGpCRDR3UElBVQpOYitwUFY4ek9Bc0dmTXJzU0h5K2RuTysyLzZoR2FRWE1CVXhFekFSQmdOVkJBTU1DbkpoY0dodlpYTjBaWEtDCkNRQ1BGL1VxaXJUUWFUQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBVEFMQmdOVkhROEVCQU1DQmFBd0ZRWUQKVlIwUkJBNHdESUlLY21Gd2FHOWxjM1JsY2pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVdENFIvWnp0RUwxcwpXcDkyajVjS3BqaUNHdkMrUytnUTJENnFyaURMd3labDU3Zkh4MkVleHVMSytGV08yQlk0cjMrdGNsTWNhakpoClB0TTZXMWlWUmRvTjZQUkQ3Mi84R05FSUNXN1pUOWVjNXBzRDUzT05FVHFTc0RySnRHTDBxTEdnUTlQb0w2MmIKankvUDRPYkJIQWQ2bjdOU1hqUHVJV2FsQWJBMFUybmNJUEw0dkJJclBaSTNlbWRydlpQK1ZiR2FpNVc1d055NQpFVkNZSmtQWjNwNW40Vm9yb3Y2djBZWlVmOEZoeXUxbWY2K0Vxd0w1Q3VLOUdrV0Q1elY0UFFQZGFKS09hdGpOCktoUHNxUUtaWEgzdEEyT1RZRjY2U0lQM2dNREUxYk5pU2l4blVjQXNBVzZjUGFGR2NHL2dJZkVaRlN2L1FEK1kKZmpBbkhPNmRmZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K","privatekey":"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRREc3OVlhUWtKdWtiajEKdnlVbDJLYUxnL3R0ZzdZT2M0OEtNcC9HNHZHR2xCT1M2MEUxaGIxTjF3ZU9tOHdzMG1lZHlWT0xpTTRST2RqZQpjcUdvZ0RENXVybDF4YUlidmlCOFg2TFB0NkpvZzdNUjZDVnpZeWFudU1QTnlPNDJyNDZQRHBRQklQOE9RY3Z0CiszUUZMVVNwRmgxSTFLUjFUKzlFT3FEd1hwNmJHYTZCTTlEUi9FR2hXWjl3SGFwekpiVzJkR05YenpYbnZpWlQKRk5YbnMvb3R6SlVqU05uVk5PSUhHeWNqdnJqM3RkbHdYU21GZFN2NlF2VmlXVDhJZGtkbTl4eThOMUt3ZUNjMApjWDYyUFFUTkl6S21HbWVraUNvSzhoS2xlTnU5eVY0UmhrRFJRZS9jYTQ5Vy9WTGFUN1h3T3Y3SEVIN0VlV0ZlCjI1K0d5ZnUzQWdNQkFBRUNnZ0VBV0loMzhpdTJ3TnBkUkJDVENhckhRNk96QzJQb2E3b0YySFg3SVZueVB3QTcKVGRFZ3JoOGN4ajJDQVhkWWdFSUxGdTk0SE1yL1dpOHlVcDBWVUpYc05kZGhuZ1ljUk5oeVFLZVhIM1lMOHhOWgphQWkyVWdtNE5FQkg4NWNPWEl2NGw3WFhMRUZ4QVBsTE5sZ0hwQjRuUmxDdks3Qm1tRWJBcHM2b3ZSQis2V3JVCkRBWTc0UDNPTi9EMmxyczVNSzlCdlA1d0FsZml1L0x3MTV4NE1UVEE2MkxHNU1remUxV2d0VGtXdnN0VUNXZUUKYW9zQ21tbVhwUGJvR2ZzRXcvSGpWdnZ6UFNKMDhid0U0Mlk2VUFtMGgzWjdMQ1o5ajJtazBsS2NpdStzYndoKwpGL3VvZHdMc2d3bGErNGFGN3g4ZW9rb0RCeVRjVSt1VUVaZWR3MEVKb1FLQmdRRC92ejhFTkM3Q3pSR2VBWjR0Cjhobkdnd2FjbXRjRmVHTHVWVG5iY3ZIZ2EwbVpabk5jdHdpRVlHMm9CYWtkWFcwTmN5WU1tQWlFZXczNTk2Q3QKakxzY0ViSEhMYmV4OGNHWTZlM3gwRFhPTkVGYlBNUnFUTWtIZytIS2tHbWxES3EzUkNxc2RzYnd3T3EyaEd6dApCNnp2SHNuUXlXeEtnMlE2bXVhckpXaUpYd0tCZ1FESElqVEUrQ2pTWkVvZ0E3dG1zN1NkR0cyY0NjNnB0RWRrCmZPZWFGVzJPWDlia2JjakxXcm9zRmpSVm1nbVRXSFZNcnBmR3p5aVBKTWNtanZxbnQzYklVU2JXK2xKMWdZL0sKSTkyL3Q0K09PRTRUL0xYZ09Hc2lOajh1R3ZTMkt2VnNXOE4yMW8vMkE3TklDcEZlTlFuRnFpcW1vazRzV1FjdAprUCtVc3lBMHFRS0JnRUViUXNPak5UUktXRzNOSTZPMnVuRWE4aGYwSTBFMVFKcEVBQktwMUlHNVRtZEsrWnRrCnpUcEdBaVNBTEdsWlcyWE5KcWFXSGJUOFRyYVFIOHVPeENPRkxhanpMb3lTYXlLdWl2REFmTEllQTNWaXB1NFkKMWlTZm9sK2JIQW4waTVGVVBUamlsQXErVWdKYy9BM3JvazdObTdzWFRBWThKTXYybXpwK3Izb3BBb0dBZit1bApZbkxZSm05dWZxcG5GRTZVMCtZQlk1K1pOc01zcVl6amFzUWhJTGpJWHUxM2M4clFsY21kek8rcS94QndLZFp1CmdiUktKY3BHZEtxY3NtalUwVkh3VldGdzN6TmZuMGJ6Q0ZsdXlybTR6bllraitrdVNVZjN4akppeVROSGZWaGwKZEUzWkpQeXppcS9mT2xsdjhaNml6M0NzTHlqeHgzL0I3MUF5ZkNFQ2dZQk5KckJEdnRSZDRCbmVXQjI5Mk84MQpBU0JpWnNPaHFDMnhSWWg1YnYyVFA2clpQd0h0cGV5MmJEK21iQVpLd003TDRKeHJxK3c0aERTN2EwRlowUm1rCi9yRlpvSjR3MDZWNGM2ZndyZG9WZmRvWE5zNkViQmd1ekxab0YyOFNUc3pOZGhFelJkdFNyWWxlalM1UnVDV2UKbUJ1L0g1d1lBNFFtUU9hRzMranFVZz09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K","certificatechain":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhxZ0F3SUJBZ0lKQUk4WDlTcUt0TkJwTUEwR0NTcUdTSWIzRFFFQkN3VUFNQlV4RXpBUkJnTlYKQkFNTUNuSmhjR2h2WlhOMFpYSXdIaGNOTWpJd016STNNVGswTXpBMVdoY05Nekl3TXpJME1UazBNekExV2pBVgpNUk13RVFZRFZRUUREQXB5WVhCb2IyVnpkR1Z5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCCkNnS0NBUUVBdUlqRXJzc0hHSFR3TmNFbjhVTmlKQjErQ0lzL2Q2aklVaXRjUlFJcEhseVJPYzMxaDNyOGlkV0oKK2pGNkFSSndXQThIcmRKYTVCTFhYK3BMWWtMblQ1V2xBVjZkNi9FT2xoUDlCM2tyNHE2ODB0TFhUM3J3UitOdAo0ZTZ0MnUzbjFIS0tsMGM0U25xRGY2b1NjRzE5SGh5OWcvbmp6eFpLVXhZd21tWDRZZXdsSnZNSXZ0VnA5M2JFClQ1MjdJdk5lcFN4MXBBTmhtLzVTRW1zQ3MwQ2pENmZZOXNrcWUra3piZE1TOFhNZlZQYkVXUzdjcG9lZERpSFEKdTVRQVhjSmxnRUVCTjMvbG5JZEpxQ0xQOEFTV2hWd3puSmNEemc5UEcrTlZ4S1A1MHV0bDdROHdsd0Z0R2d4UAp5REhvamNsbVBtQ291UmdHb2RrMnJBQ0lYME9PTFFJREFRQUJvNEdFTUlHQk1CMEdBMVVkRGdRV0JCUTF2Nms5Clh6TTRDd1o4eXV4SWZMNTJjNzdiL2pCRkJnTlZIU01FUGpBOGdCUTF2Nms5WHpNNEN3Wjh5dXhJZkw1MmM3N2IKL3FFWnBCY3dGVEVUTUJFR0ExVUVBd3dLY21Gd2FHOWxjM1JsY29JSkFJOFg5U3FLdE5CcE1Bd0dBMVVkRXdRRgpNQU1CQWY4d0N3WURWUjBQQkFRREFnRUdNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUN6YXU1QlNnSituZy92Cnd2SHVDTnEyZWg5c1M1M3pmVUlQeTZqTUZrZHprelVZTmI1WjFRK1hjb21GbU9xOVVmaWcxN2dZdUR3WC9nMlMKVklDMVJDdWxwVTNORnNLOEhrSDdjdVFPOGNjSnlWc3JtUndPSFhabmtwTnBoYXI4RFQvSjU5d3FNU09ZZUJQYgpuQU41T0piaUF0NlRBNmRsUXJidkFvWG04dXdHMjFSU1N1VHQ5UElsY3NGallQazhiQWJ0dXdldEVnYjVuNkhoClhhczA1S0dteENmZDZxNHAxYUxITkVpNTVSejg0bEVsVHVNZlA0ZEwyZjIzUnFncmpEQmNDRmEwN1owZHJNdjcKbERYNEovaVpXY08zWXJJWXppcVg5M015UzNSUCtrYXAvV0dIYlZDcWtpZ2lTODZwQkY1NDh3OWxXQ0xJai9kTgozRTI2V24zNgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="}}`
// yeah the string is long lol
var body ResponseBody
if err := json.Unmarshal([]byte(mystring), &body); err != nil {
fmt.Println(fmt.Errorf("failed unmarshaling response | %s", err.Error()))
}
fmt.Println(body.Error.ErrorMessage)
certChain, err := base64.StdEncoding.DecodeString(body.PkiData.Certificate)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(certChain)
}
type PkiGenerationInput struct {
TeacherUsername string `json:"teacherusername"`
}
type Response struct {
Headers ResponseHeaders `json:"headers"`
Body ResponseBody `json:"body"`
}
type ResponseHeaders struct {
ContentType string `json:"Content-Type"`
}
type ResponseBody struct {
PkiData ParsablePkiData `json:"pkidata"`
Error struct {
ErrorMessage string `json:"errormessage"`
ErrorType string `json:"errortype"`
} `json:"error"`
}
type ParsablePkiData struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"privatekey"`
CertificateChain string `json:"certificatechain"`
}
ex. https://go.dev/play/p/C6ahqdjZkkK
CodePudding user response:
Answer to synthetize all of the comments :
First of all, my "dumb mistake" was because I tried to decode the wrong variable :
// mystring needs to be replaced by body.PkiData.Certificate
base64.StdEncoding.DecodeString(mystring)
But the research led us to discover that the json.Unmarshal()
function decodes base64 by itself when the result type matches what the declared type. Given the fact the encoded data was a []byte
, I just replaced the string
type by a []byte
in the struct.
That allows to create a much more simple version of the previous code :
type ResponseBody struct {
PkiData PkiData `json:"pkidata"`
}
type PkiData struct {
Certificate []byte
PrivateKey []byte
CertificateChain []byte
}
var body ResponseBody
if err := json.Unmarshal(rawResp.Payload, &body); err != nil {
return PkiData{}, fmt.Errorf("failed unmarshaling response | %s", err.Error())
}