Files
ipsw/pkg/devicetree/image.go

69 lines
1.7 KiB
Go

package devicetree
import (
"bytes"
"errors"
"fmt"
"github.com/blacktop/ipsw/internal/utils"
"github.com/blacktop/ipsw/pkg/img3"
"github.com/blacktop/ipsw/pkg/img4"
)
var ErrEncryptedDeviceTree = errors.New("encrypted device tree")
// ParseImg3Data parses a img3 data containing a DeviceTree
func ParseImg3Data(data []byte) (*DeviceTree, error) {
// First try to extract data (handles both encrypted detection and data extraction)
extractedData, err := img3.ExtractData(data)
if err != nil {
// Check if this might be an encrypted IMG3 by parsing and looking for KBAG tags
i, parseErr := img3.ParseImg3(data)
if parseErr == nil {
for _, tag := range i.Tags {
magic := string(utils.ReverseBytes(tag.Magic[:]))
if magic == "KBAG" {
return nil, ErrEncryptedDeviceTree
}
}
}
return nil, fmt.Errorf("failed to extract IMG3 data: %v", err)
}
dr := bytes.NewReader(extractedData)
dtree, err := parseDeviceTree(dr)
if err != nil {
return nil, fmt.Errorf("failed to parse IMG3 device tree data: %v", err)
}
return dtree, nil
}
// ParseImg4Data parses a img4 data containing a DeviceTree
func ParseImg4Data(data []byte) (*DeviceTree, error) {
// NOTE: openssl asn1parse -i -inform DER -in DEVICETREE.im4p
im4p, err := img4.ParsePayload(data)
if err != nil {
return nil, fmt.Errorf("failed to parse Img4 payload: %v", err)
}
// Check if the payload is encrypted before attempting to parse
if im4p.Encrypted {
return nil, ErrEncryptedDeviceTree
}
data, err = im4p.GetData()
if err != nil {
return nil, fmt.Errorf("failed to get Img4 data: %v", err)
}
dtree, err := parseDeviceTree(bytes.NewReader(data))
if err != nil {
return nil, fmt.Errorf("failed to parse Img4 device tree data: %v", err)
}
return dtree, nil
}